/// @page page_use_prot How to Use Defined Custom Protocol
/// @tableofcontents
/// This page is oriented to client application developers. It provides instructions
/// on how to use protocol defininition after it was developed following
/// @ref page_define_prot instructions. All the examples below will use
/// @b my_protocol namespace for classes that are expectected to be already
/// defined by the custom protocol implementation.
///
/// @section page_use_prot_headers Headers and Libraries
/// The protocol definition as well as @b Marshalling library are headers-only. The
/// protocol definition should already include all the required headers from
/// the @b Marshalling library. The client application will have to include only relevant
/// headers from the protocol definition.
///
/// @section page_use_prot_paths Paths and Namespaces
/// All the classes provided by the @b Marshalling library reside in @ref marshalling
/// namespace and the inner include paths start with "marshalling/". There may be
/// the case when this library being integrated into existing project that may already
/// define and use its own module (namespace) named @b marshalling. In this case it
/// should be possible to rename installation directory (@b marshalling to @b marshalling2) and
/// to run a script after library installation to replace
/// the following strings with new name:
/// @li <b>"namespace marshalling"</b> - replace with "namespace marshalling2"
/// @li @b "nil::marshalling::" - replace with "marshalling2::"
/// @li @b "marshalling/" - replace with "marshalling2/"
///
/// @section page_use_prot_error_handling Error Handling
/// The Marshalling library is intended to be used in embedded systems (including
/// bare metal), which means the library does not use exceptions to report errors.
/// The runtime errors are reported via @ref nil::marshalling::ErrorStatus return values. All
/// pre- and post-conditions are checked using MARSHALLING_ASSERT() macro.
/// It is, just like regular standard @b assert(), is compiled in if @b NDEBUG symbol
/// is not defined. In case the provided condition doesn't hold true, the macro
/// checks whether custom assertion failure behaviour was registered. If yes,
/// the registered custom assertion failure report is invoked, otherwise the
/// standard failure report used by standard @b assert() macro is used. If Marshalling
/// library is used in bare metal environment without standard library, the
/// @b NOSTDLIB symbol should be defined. In this case infinite loop is a default
/// assertion failure report behaviour.
///
/// See @ref page_assert for detail on how to define custom assertion failure
/// behaviour.  
///
/// @section page_use_prot_interface Defining Message Interface Class
/// The protocol definition is expected to define extendable message interface
/// class pinning only serialization endian and numeric message ID type (most
/// probably enum).
/// @code
/// namespace my_protocol
/// {
///     // Used IDs definition
///     enum msg_id : std::uint8_t
///     {
///         MsgId_Message1,
///         MsgId_Message2,
///         MsgId_Message3,
///         ...
///     };
///
/// template <typename... TOptions>
/// using Message = 
///     nil::marshalling::Message<
///         nil::marshalling::option::big_endian, // endian
///         nil::marshalling::option::msg_id_type<msg_id>, // type of message ID
///         TOptions...
///     >;
///
/// } // namespace my_protocol
/// @endcode
/// Such interface class is NOT polymorphic, it defines the following inner types
/// @code
/// namespace my_protocol
/// {
///     
/// class Message : public nil::marshalling::Message
///     // nil::marshalling::field_type class with the same endian option.
///     // Can (and should) be provided as a base class to all the
///     // fields.
///     typedef nil::marshalling::field_type<.../* Same endian option*/> field_type;
///
///     // type of the ID, same as the one passed with nil::marshalling::option::msg_id_type
///     typedef msg_id msg_id_type;
///
///     // type of the ID, when it is passed as a parameter and/or returned from the function:
///     typedef msg_id msg_id_param_type;
///
/// };
///
/// } // namespace my_protocol
/// @endcode
/// @b Note the existence of @b msg_id_type and @b msg_id_param_type. When the
/// type used for message ID is simple integral one or enum, these types
/// are equal.
/// However, if some other type is used, such as std::string, then @b msg_id_param_type
/// is a const-reference to @b msg_id_type.
///
/// The message interface class may be extended with multiple options, which 
/// automatically add virtual functions, and hence create polymorphic behaviour
/// relevant to the client application.
///
/// In general, all the API functions that are being added to the interface (and described below)
/// use <a href="https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface">Non-Virtual Interface</a>
/// idiom:
/// @code
/// class MyMessage
/// {
/// public:
///     void someFunction(...)
///     {
///         ...; // Pre-conditions check and/or other common operations
///         someFunctionImpl(...); // Invocation of polymorphic functionality
///         ...; // Post-conditions check and/or other common operations
///     }
///
/// protected:
///     virtual void someFunctionImpl(...) = 0; // Must be implemented in the derived class
/// };
/// @endcode
/// The polymorphic behaviour is exposed via @b protected virtual functions having
/// the same name, but with @b Impl suffix.
///
/// All the variants of message interface class that are going to be described
/// below are descendants of @ref nil::marshalling::Message class. Please refer to the
/// documentation of the latter for detailed info on the described functions and
/// their parameters.
///
/// @subsection page_use_prot_interface_id_retrieve Polymorphic Retrieval of Message ID
/// When there is a need to be able to polymorphically retrieve message ID,
/// the nil::marshalling::option::id_info_interface option needs to be used. Note, that this
/// option requires presence of @ref nil::marshalling::option::msg_id_type (which is expected to
/// be used in protocol definition) to specify type
/// of the message ID in order to work properly.
/// @code
/// using MyMessage =
///     my_protocol::Message<
///         nil::marshalling::option::id_info_interface,
///         ...
///     >;
/// @endcode
/// It adds the following functions:
/// @code
/// class MyMessage
/// {
/// public:
///     // API function to retrieve ID of the function
///     msg_id_param_type get_id() const
///     {
///         return get_id_impl();
///     }
///
/// protected:
///     virtual msg_id_param_type get_id_impl() const = 0; // Automatically implemented in the actual message class
/// }
/// @endcode
/// The usage of nil::marshalling::option::id_info_interface without nil::marshalling::option::msg_id_type
/// will be ignored, and @b get_id() as well as @b get_id_impl() member functions
/// won't be created.
///
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_get_id()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::id_info_interface option has been used, i.e.
/// the message interface class defines mentioned earlier
/// functions.
///
/// @subsection page_use_prot_interface_read Polymorphic Read of Payload (Deserialization)
/// If the implementation requires polymorphic read and process of input messages, the @b read()
/// operation needs to be added to the interface. It is achieved by using 
/// @ref nil::marshalling::option::read_iterator option to provide a type of the iterator that
/// is going to be used for reading:
/// @code
/// using MyMessage = 
///     my_protocol::Message<
///         ...
///         nil::marshalling::option::read_iterator<const std::uint8_t*>,
///         ...
///     >;
/// @endcode
/// As the result the interface class defines the following types and functions:
/// @code
/// class MyMessage
/// {
/// public:
///     // type of the the iterator used for reading, the same as provided with
///     // nil::marshalling::option::read_iterator option.
///     typedef ... read_iterator;
///
///     // API function to perform read
///     nil::marshalling::ErrorStatus read(read_iterator& iter, std::size_t len)
///     {
///         return readImpl(iter, len);
///     }
///
/// protected:
///     // Expected to be overriden in the derived class.
///     virtual nil::marshalling::ErrorStatus readImpl(read_iterator& iter, std::size_t len)
///     {
///         return nil::marshalling::ErrorStatus::not_supported;
///     }
/// }
/// @endcode
/// Please @b note, that Marshalling library doesn't impose any restrictions on
/// how the input data is collected and stored. It is a responsibility of the 
/// @b caller to allocate and maintain the input buffer, while providing only an 
/// iterator for read operation. @n
/// Also @b note, that iterator is passed by reference, which allows advancing 
/// operator when read operation is performed. @n
/// For example:
/// @code
/// std::size_t readMessage(MyMessage& msg, const std::uint8_t* buf, std::size_t len)
/// {
///     MyMessage::read_iterator readIter = buf;
///     auto es = msg->read(readIter, len); // readIter is advanced in the read operation
///     if (es != nil::marshalling::ErrorStatus::success) {
///         ... // Report and handle error
///         return 0U; 
///     }
///     
///     // Report number of processed bytes from buffer:
///     auto bytesCount = std::distance(MyMessage::read_iterator(buf), readIter);
///     return bytesCount;
/// }
/// @endcode
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_read()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::read_iterator option has been used, i.e.
/// the message interface class defines mentioned earlier
/// types and functions.
///
/// @subsection page_use_prot_interface_write Polymorphic Write of Payload (Serialisation)
/// If the implementation requires polymorphic serialization of the messages and sending them over I/O
/// link, the @b write() operation needs to be added to the interface. It is 
/// achieved by using  nil::marshalling::option::write_iterator option to provide a type of
/// the iterator that is going to be used for writing:
/// @code
/// using MyMessage = 
///     my_protocol::Message<
///         ...
///         nil::marshalling::option::write_iterator<std::back_insert_iterator<std::vector<std::uint8_t> > >,
///         ...
///     >;
/// @endcode
/// As the result the interface class defines the following types and functions:
/// @code
/// class MyMessage
/// {
/// public:
///     // type of the the iterator used for writing, the same as provided with
///     // nil::marshalling::option::write_iterator option.
///     typedef ... write_iterator;
///
///     // API function to perform write
///     nil::marshalling::ErrorStatus write(write_iterator& iter, std::size_t len)
///     {
///         return write_impl(iter, len);
///     }
///
/// protected:
///     // Expected to be overriden in the derived class.
///     virtual nil::marshalling::ErrorStatus write_impl(write_iterator& iter, std::size_t len)
///     {
///         return nil::marshalling::ErrorStatus::not_supported;
///     }
/// }
/// @endcode
/// Please @b note, that Marshalling library doesn't impose any restrictions on
/// storage type for the output buffer. It is a responsibility of the 
/// @b caller to allocate and maintain the output buffer, while providing only an 
/// iterator for write operation. In the example above the output buffer
/// is chosen to be @b std::vector<std::uint8_t> and the write operation will
/// be performed using @b push_back() calls on this vector (due to @b std::back_insert_iterator
/// being chosen as @b write_iterator). @n
/// Also @b note, that iterator is passed by reference, which allows advancing 
/// operator when write operation is performed. 
///
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_write()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::write_iterator option has been used, i.e.
/// the message interface class defines mentioned earlier
/// types and functions.
///
/// @subsection page_use_prot_interface_length Polymorphic Serialisation length Retrieval
/// Sometimes it may be needed to polymorphically retrieve the serialization length of the message
/// in order to be able to reserve or allocate enough space for output buffer.
/// The Marshalling library provides nil::marshalling::option::length_info_interface option that
/// adds @b length() member function to the interface.
/// @code
/// using MyMessage = 
///     my_protocol::Message<
///         ...
///         nil::marshalling::option::length_info_interface,
///         ...
///     >;
/// @endcode
/// This option adds the following functions to the interface definition:
/// @code
/// class MyMessage
/// {
/// public:
///     // Retrieve the serialization length
///     std::size_t length() const
///     {
///         return length_impl();
///     }
///
/// protected:
///     virtual std::size_t length_impl() const = 0; // Implemented in the derived class
/// };
/// @endcode
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_length()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::length_info_interface option has been used, i.e.
/// the message interface class defines mentioned earlier
/// functions.
///
/// @subsection page_use_prot_interface_valid Polymorphic Validity Check
/// Sometimes it may be needed to be able to check whether the message contents
/// (fields) have valid values. The Marshalling library provides nil::marshalling::option::valid_check_interface
/// option that adds @b valid() member function to the interface:
/// @code
/// using MyMessage =
///     my_protocol::Message<
///         ...
///         nil::marshalling::option::valid_check_interface,
///         ...
///     >;
/// @endcode
/// This option adds the following functions to the interface definition:
/// @code
/// class MyMessage
/// {
/// public:
///     // Retrieve the serialization length
///     bool valid() const
///     {
///         return valid_impl();
///     }
///
/// protected:
///     virtual bool valid_impl() const
///     {
///         return true; // By default all messages are valid, can be overridden in derived class.
///     }
/// };
/// @endcode
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_valid()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::valid_check_interface option has been used, i.e.
/// the message interface class defines mentioned earlier
/// functions.
///
/// @subsection page_use_prot_interface_handle Polymorphic Dispatch Message for Handling
/// When new data arrives on I/O link, it's transport framing is going to
/// be processed (described in detailed in @ref page_use_prot_transport section below).
/// and new message object is going to be created. It's going to be returned
/// as a smart pointer (std::unique_ptr) to the defined interface class (@b MyMessage).
/// The actual type of this message object needs to be recognised and message
/// properly handled. Using simple
/// switch statement on message ID (returned by @b get_id() interface function)
/// can be very @b INEFFICIENT. The Marshalling library provides much more efficient way
/// to dispatch messages to appropriate handler. 
///
/// The handler class needs to be forward declared and passed
/// to the definition of @b MyMessage interface via nil::marshalling::option::handler option.
/// @code
/// // Forward declaration
/// class MyHandler;
///
/// using MyHandler = 
///     my_protocol::Message<
///         ...
///         nil::marshalling::option::handler<MyHandler>,
///         ...
///     >;
/// @endcode
/// When this option is used the @b MyMessage will define the following interface
/// types and functions:
/// @code
/// class MyMessage
/// {
/// public:
///     // The same type as passed via nil::marshalling::option::handler option
///     typedef ... handler;
///
///     // Return type of the dispatch function, which is the same as return type of
///     // every handler::handle() member function
///     typedef ... DispatchRetType;
///
///     // Dispatch this message to handler
///     DispatchRetType dispatch(handler& handler)
///     {
///         return dispatch_impl(handler);
///     }
///
/// protected:
///     virtual DispatchRetType dispatch_impl(handler& handler) = 0; // Must be implemented in the derived class
/// };
/// @endcode
/// More detail about polymorphic dispatching and handling will be provided
/// below in @ref page_use_prot_handling section.
///
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_dispatch()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::handler option has been used, i.e.
/// the message interface class defines mentioned earlier
/// types and functions.
///
/// @subsection page_use_prot_interface_refresh Keeping Message Contents in a Consistent State
/// Some communication protocol may define fields that depend on other fields.
/// For example, bits in a bitmask field may be used to define whether some
/// optional fields exist. Or the information about amount of elements in 
/// the list to follow may reside in an independent numeric field. @n 
/// After updating such fields directly, using the interface of the message object,
/// the message contents may end up being in an inconsistent (or invalid) state.
/// There may be a need to polymorphically normalise the state of the message object. The
/// Marshalling library provides nil::marshalling::option::refresh_interface option, that adds
/// @b refresh() member function to the message interface.
/// @code
/// using MyMessage = 
///     nil::marshalling::Message<
///         ...
///         nil::marshalling::option::refresh_interface,
///         ...
///     >;
/// @endcode
/// This option adds the following functions to the interface definition:
/// @code
/// class MyMessage
/// {
/// public:
///     // Refresh message contents
///     bool refresh()
///     {
///         return refresh_impl();
///     }
///
/// protected:
///     virtual bool refresh_impl()
///     {
///         return false;
///     }
/// };
/// @endcode
/// Note, that the @b refresh() member function returns boolean value, which
/// is expected to be @b true in case at least one of the internal fields has
/// been updated, and @b false if message state remains unchanged. @n
/// Also note, that interface provide default implementation of @b refresh_impl()
/// virtual function. The message object that require proper "refresh" functionality
/// may just override it with proper implementation.
///
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_refresh()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::refresh_interface option has been used, i.e.
/// the message interface class defines mentioned earlier
/// functions.
///
/// @subsection page_use_prot_interface_name Polymorphic Message Name Retrieval
/// Some applications may require knowledge about and report the name of the received / sent
/// message. The @b Marshalling library provides @ref nil::marshalling::option::name_interface
/// option, that adds @b name() member function to the message interface
/// (see @ref nil::marshalling::Message::name()).
/// @code
/// using MyMessage = 
///     nil::marshalling::Message<
///         ...
///         nil::marshalling::option::name_interface,
///         ...
///     >;
/// @endcode
/// This option adds the following functions to the interface definition:
/// @code
/// class MyMessage
/// {
/// public:
///     // Retrieve name of the message 
///     const char* name() const
///     {
///         return name_impl();
///     }
///
/// protected:
///     virtual const char* name_impl() const = 0;
/// };
/// @endcode
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_name()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::name_interface option has been used, i.e.
/// the message interface class defines mentioned earlier
/// functions.
///
/// @subsection page_use_prot_interface_virt_destructor Virtual Destructor
/// By default the @ref nil::marshalling::Message class defines its
/// destructor as @b virtual if and only if it exhibits a polymorphic behaviour, 
/// i.e. if there is at least one other virtual function defined. There are a couple of
/// ways to change this default behaviour.
/// @li If the definition of the common message interface class using 
///     exhibits polymorphic 
///     behaviour (i.e. has other virtual functions), but mustn't define its
///     destructor as @b virtual, use @ref nil::marshalling::option::no_virtual_destructor
///     option in the interface class definition.
///     @code
///     using MyMessage = 
///         my_protocol::Message<
///             ...,
///             nil::marshalling::option::no_virtual_destructor
///         >;
///     @endcode
/// @li If the definition of the common interface class 
///     doesn't have any virtual function, but still requires an ability to 
///     be polymorphically deleted, i.e. must have virtual destructor, just 
///     inherit from @b my_protocol::Message and define the destructor as virtual.
///     @code
///     class MyMessage : public 
///         my_protocol::Message<>
///     {
///     public:
///         virtual ~MyMessage() = default;
///     };
///     @endcode
///
/// @subsection page_use_prot_interface_summary Interface options_type Summary
/// All the options introduced above can be used in any order. They can also
/// be repeated multiple times. However, the option that was defined first takes
/// priority over (or overrides) the same option defined later. @n 
/// For example, the definition below defines @b write_iterator to be
/// <b>std::uint8_t*</b>, because it was defined with first 
/// nil::marshalling::option::write_iterator option:
/// @code
/// using MyMessage = 
///     my_protocol::Message<
///         ...
///         nil::marshalling::option::write_iterator<std::uint8_t*>,
///         ...
///         nil::marshalling::option::write_iterator<std::back_insert_iterator<std::vector<std::uint8_t> >,
///         ...
///     >;
/// @endcode  
/// The definition below gives a full interface of all
/// the introduced functions: @b get_id(), @b read(), @b write(), @b dispatch(),
/// @b length(), @b valid(), @b refresh(), and @b name().
/// @code
/// using MyMessage = my_protocol::Message<
///     nil::marshalling::option::id_info_interface, // Add an ability to retrieve message ID value
///     nil::marshalling::option::read_iterator<const std::uint8_t*>, // Use const std::uint8_t* as iterator for reading
///     nil::marshalling::option::write_iterator<std::uint8_t*>, // Use std::uint8_t* as iterator for writing
///     nil::marshalling::option::handler<MyHandler>, // My MyHandler class declared earlier as a handler for messages
///     nil::marshalling::option::length_info_interface, // Add an ability to retrieve serialization length
///     nil::marshalling::option::valid_check_interface, // Add an ability to check contents validity
///     nil::marshalling::option::refresh_interface,  // Add an ability to refresh message contents
///     nil::marshalling::option::name_interface // Add an ability to retrieve message name
/// >;
/// @endcode
///
/// @section page_use_prot_messages Protocol Messages
/// The protocol messages are expected to be defined as template classes, receiving
/// at least one template parameter, which specifies the application specific interface 
/// class. For example
/// @code
/// namespace my_protocol
/// {
/// 
/// namespace message
/// {
///
/// template <typename TBase>
/// class Message1 : public
///     nil::marshalling::MessageBase<
///         TBase,
///         ...
///     >
/// {
///     ...
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// The interface class that was defined for the application (@b MyMessage) needs
/// to be passed as @b TBase template parameter. The defined message class 
/// extends @ref nil::marshalling::MessageBase, which in turn extends provided interface
/// class @b TBase, which in turn extends @ref nil::marshalling::Message. The inheritence
/// hierarchy may look like this:
/// @diafile message_class_hierarchy.dia
///
/// Due to the fact that every protocol message class extends @ref nil::marshalling::MessageBase,
/// the detailed documentation on available member types and functions
/// can be viewed on @ref nil::marshalling::MessageBase reference page.
///
/// All the protocol message classes implement non-virtual functions that may be
/// used to implement polymorphic behavior. These function has the same name as
/// described earlier interface, but start with @b do* prefix.
///
/// @li @b do_read() - implements message read functionality (see @ref nil::marshalling::MessageBase::do_read())
/// @li @b do_write() - implements message write functionality (see @ref nil::marshalling::MessageBase::do_write())
/// @li @b do_length() - implements message serialization length calculation (see @ref nil::marshalling::MessageBase::do_length())
/// @li @b do_valid() - implements message contents validity check (see @ref nil::marshalling::MessageBase::do_valid())
/// @li @b do_refresh() - implements bringing message to a consistent state (see @ref nil::marshalling::MessageBase::do_refresh())
///
/// Based on the requested polymorphic functionality, the @b nil::marshalling::MessageBase
/// class automatically implements virtual @b *Impl() member functions (but only when needed).
/// @code
/// namespace my_protocol
/// {
/// 
/// namespace message
/// {
///
/// template <typename TBase>
/// class Message1 : public
///     nil::marshalling::MessageBase<
///         TBase,
///         ...
///     >
/// {
/// public:
///     template <typename TIter>
///     nil::marshalling::ErrorStatus do_read(TIter& iter, std::size_t len) {...}
///
///     template <typename TIter>
///     nil::marshalling::ErrorStatus do_write(TIter& iter, std::size_t len) const {...}
///
///     ...
/// protected:
///     virtual nil::marshalling::ErrorStatus readImpl(read_iterator& iter, std::size_t len)
///     {
///         return do_read(iter, len);
///     }
///
///     virtual nil::marshalling::ErrorStatus write_impl(write_iterator& iter, std::size_t len) const
///     {
///         return do_write(iter, len);
///     }
///
///     ...
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// Such architecture allows usage of non-virtual functions when actual type
/// of the message is known. For example
/// @code
/// template <typename TMsg>
/// void writeMessage(const TMsg& msg)
/// {
///     auto es = msg.do_write(...);
///     ...
/// }
/// @endcode
/// and using polymorphic behaviour when not
/// @code
/// void writeMessage(const MyMessage& msg)
/// {
///     auto es = msg.write(...);
///     ...
/// }
/// @endcode
/// Every message has zero or more fields, which are stored in @b std::tuple
/// as private members of @ref nil::marshalling::MessageBase. The access to the fields
/// can be obtained using @b fields() member function (see @ref nil::marshalling::MessageBase::fields()).
///
/// However, every message that has at least one field is expected to use
/// @ref MARSHALLING_MSG_FIELDS_ACCESS() macro to provide names to inner fields.
/// @code
/// namespace my_protocol
/// {
/// 
/// namespace message
/// {
///
/// template <typename TBase>
/// class Message1 : public
///     nil::marshalling::MessageBase<
///         TBase,
///         ...
///     >
/// {
/// public:
///     MARSHALLING_MSG_FIELDS_ACCESS(value1, value2, value3);
///     ...
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// It is equivalent of having the following types and member functions defined.
/// @code
/// namespace my_protocol
/// {
/// 
/// namespace message
/// {
///
/// template <typename TBase>
/// class Message1 : public
///     nil::marshalling::MessageBase<
///         TBase,
///         ...
///     >
/// {
/// public:
///     enum FieldIdx
///     {
///         FieldIdx_value1,
///         FieldIdx_value2,
///         FieldIdx_value3,
///         FieldIdx_numOfValues
///     }
///
///     // Access the "value1" field
///     auto field_value1() -> decltype(std::get<FieldIdx_value1>(fields()))
///     {
///         return std::get<FieldIdx_value1>(fields());
///     }
///
///     // Access the "value1" field (const variant)
///     auto field_value1() const -> decltype(std::get<FieldIdx_value1>(fields()))
///     {
///         return std::get<FieldIdx_value1>(fields());
///     }
///
///     // Access the "value2" field
///     auto field_value2() -> decltype(std::get<FieldIdx_value2>(fields()))
///     {
///         return std::get<FieldIdx_value2>(fields());
///     }
///
///     // Access the "value2" field (const variant)
///     auto field_value2() const -> decltype(std::get<FieldIdx_value2>(fields()))
///     {
///         return std::get<FieldIdx_value2>(fields());
///     }
///
///     // Access the "value3" field
///     auto field_value3() -> decltype(std::get<FieldIdx_value3>(fields()))
///     {
///         return std::get<FieldIdx_value3>(fields());
///     }
///
///     // Access the "value3" field (const variant)
///     auto field_value3() const -> decltype(std::get<FieldIdx_value3>(fields()))
///     {
///         return std::get<FieldIdx_value3>(fields());
///     }
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// As the result every message field can be accessed by index
/// @code
/// using MyMessage1 = my_protocol::Message1<MyMessage>;
/// MyMessage1 msg;
/// auto& msg1Fields = msg.fields(); // access to std::tuple of message fields.
/// auto& value1Field = std::get<MyMessage1::FieldIdx_value1>(msg1Fields);
/// auto& value2Field = std::get<MyMessage1::FieldIdx_value2>(msg1Fields);
/// auto& value2Field = std::get<MyMessage1::FieldIdx_value2>(msg1Fields);
/// @endcode
/// or by name
/// @code
/// auto& value1Field = msg.field_value1();
/// auto& value2Field = msg.field_value2();
/// auto& value2Field = msg.field_value3();
/// @endcode
///
/// @section page_use_prot_fields Message fields_type
/// In order to continue with the tutorial, it is paramount to understand a 
/// concept of @b fields, which are abstractions around value storage primitives and/or objects, 
/// such as integral values, floating point values, strings, arrays, etc..
/// Every @b field class is defined in @ref nil::marshalling::field namespace and
/// exposes predefined interface in order to
/// make template meta-programming as easy as possible. As an example let's
/// take a look at @ref nil::marshalling::types::IntValue class which is used to
/// define integral value field.
/// @code
/// template <typename TBase, typename T, typename... TOptions>
/// class nil::marshalling::types::IntValue : public TBase
/// {
/// public:
///     // Define inner storage type
///     using value_type = T;
///     
///     // Get access to the stored value
///     value_type& value() { return m_value; }
///     const value_type& value() const { return m_value; }
///
///     // Read
///     template <typename TIter>
///     nil::marshalling::ErrorStatus read(TIter& iter, std::size_t len) {...}
///
///     // Write
///     template <typename TIter>
///     nil::marshalling::ErrorStatus write(TIter& iter, std::size_t len) const {...}
///
///     // Serialisation length
///     std::size_t length() const {...}
///
///     // Validity of the value
///     bool valid() const {...}
///
///     // Bring field's contents into a consistent state
///     bool refresh() {...}
///
/// private:
///     value_type m_value;
/// }
/// @endcode
/// The main things to note are that every field definition class:
/// @li receives its base class as the first 
///     template parameter. It is expected to be a variant of @ref
///     nil::marshalling::field_type with @ref nil::marshalling::option::big_endian or @ref
///     nil::marshalling::option::little_endian option to specify the serialization endian.
///     It may be inner @b field_type type of @b MyMessage interface class defined
///     earlier (@b MyMessage::field_type - documented as @ref nil::marshalling::Message::field_type)
/// @li exhibits some default behaviour which can be modified by
///     passing various options from @ref nil::marshalling::option namespace as additional template
///     parameters. The options that define how field is serialized are expected
///     to be used as part of protocol definition. The protocol definition is
///     also expected to allow passing extra options that are relevant to application
///     environment and/or behaviour (such as modifying the default storage type).
/// @li defines @b value_type inner value storage
///     type and provides @b value() member functions to access the stored value.
/// @li provides @b read() and @b write() member functions to read and write the 
///     inner value given the iterator used for reading / writing and available
///     length of the buffer.
/// @li has @b length() member function to report how many bytes are required to
///     serialise currently stored value.
/// @li provides @b valid() member function to check whether the stored value is
///     valid (within expected range of values).
/// @li has @b refresh() member function to bring its contents to consistent / valid
///     state when required.
///
/// Also note that all the member function are NON-virtual, i.e. the field 
/// abstractions do not have polymorphic behaviour.
///
/// The most important member function to a client application is @b value().
/// It allows access to the stored value. Note, that the stored value is accessed
/// by reference. It allows both get and set operations:
/// @code
/// auto myFieldValue = myField.value();
/// myField.value() = 5U;
/// @endcode
/// Other member functions are of lesser importance to the client application, 
/// they are used by the protocol definition itself to properly (de)serialise
/// message contents and provide other useful functionality.
///
/// The available fields abstractions are:
/// @li @ref nil::marshalling::types::IntValue - used to define @ref page_use_prot_fields_int_value
/// @li @ref nil::marshalling::types::EnumValue - used to define @ref page_use_prot_fields_enum_value
/// @li @ref nil::marshalling::types::BitmaskValue - used to define @ref page_use_prot_fields_bitmask_value
/// @li @ref nil::marshalling::types::Bitfield - used to define @ref page_use_prot_fields_bitfield
/// @li @ref nil::marshalling::types::Bundle - used to define @ref page_use_prot_fields_bundle
/// @li @ref nil::marshalling::types::array_list - used to define @ref page_use_prot_fields_array_list
/// @li @ref nil::marshalling::types::String - used to define @ref page_use_prot_fields_string
/// @li @ref nil::marshalling::types::FloatValue - used to define @ref page_use_prot_fields_fp_value
/// @li @ref nil::marshalling::types::Optional - used to define @ref page_use_prot_fields_optional
/// @li @ref nil::marshalling::types::Variant - used to define @ref page_use_prot_fields_variant
///
/// @subsection page_use_prot_fields_int_value Integral value fields_type
/// Integral value fields are defined using @ref nil::marshalling::types::IntValue class.
/// Its inner @b value_type type is the same as second template parameter. Most
/// integral value fields are defined and used "as-is"
/// @code
/// // base class for all the fields, usually defined by the protocol definition library
/// using MyFieldBase = nil::marshalling::field_type<nil::marshalling::option::big_endian>
///
/// // definition of integral field
/// using MyIntField = 
///     nil::marshalling::types::IntValue<
///         MyFieldBase, // base class for all the fields, defined by the protocol definition library
///         std::uint16_t
///     >;
///
/// // usage of the field
/// MyIntField field;
/// field.value() = 5; // serialized as "00 05"
/// @endcode
/// Some field's definitions may use @ref nil::marshalling::option::num_value_ser_offset
/// option, which adds predefined offset to the field before serialising and
/// subtracts it before deserialising. Classic example would be having a "year"
/// information, but serialized as offset from year @b 2000 with a single byte.
/// Such field may be defined as following:
/// @code
/// using YearField = 
///     nil::marshalling::types::IntValue<
///         MyFieldBase, 
///         std::int16_t, 
///         nil::marshalling::option::fixed_length<1>,
///         nil::marshalling::option::num_value_ser_offset<-2000>
///     >;
/// @endcode
/// @b NOTE, that while serialization takes only 1 byte, the client application
/// will use full year number without worrying about added / removed offset
/// @code
/// YearField field;
/// field.value() = 2018; // serialized as 0x12;
/// @endcode
/// Some protocols may exchange floating point values by serialising them as 
/// integral ones. For example, multiply the floating point value by 1000 before
/// the serialization, and upon reception divide the received value by 1000 to
/// get the floating point one. Such fields will be defined using @ref
/// nil::marshalling::types::IntValue type with using @ref nil::marshalling::option::scaling_ratio
/// option
/// @code
/// using MyFpField = 
///     nil::marshalling::types::IntValue<
///         MyFieldBase, // base class for all the fields, defined by the protocol definition library
///         std::int32_t,
///         nil::marshalling::option::scaling_ratio<1, 1000>
///     >;
/// @endcode
/// The inner value of such field is integral one. However, there are
/// @ref nil::marshalling::types::IntValue::get_scaled() and @ref nil::marshalling::types::IntValue::set_scaled()
/// member functions that allow get and set original floating point value without
/// worrying what math operation needs to be performed.
/// @code
/// MyFpField field;
/// field.set_scaled(1.3f);
/// assert(field.value() == 1300); 
/// auto asDouble = field.get_scaled<double>(); // equivalent to 1.3
/// @endcode
/// In addition to @b scaling, the @b Marshalling library also provides an ability
/// to specify @b units. For example, some protocol may define distance in
/// @b 1/10 of the @b millimetres. The definition of such field may look like
/// this
/// @code
/// using MyDistance = 
///     nil::marshalling::types::IntValue<
///         MyFieldBase,
///         std::int32_t,
///         nil::marshalling::option::scaling_ratio<1, 10>,
///         nil::marshalling::option::units_millimeters
/// @endcode
/// The @b Marshalling library provides a set of units conversion functions in
/// @ref nil::marshalling::units namespace. When using the provided conversion function the application developer
/// doesn't need to remember the original units and/or scaling factor. The @b Marshalling library
/// does all the math. It also prevents (at compile time) usage of wrong conversion
/// functions, say calculating time (@b milliseconds), when specified units are 
/// @b distance (@b millimetres).
/// @code
/// MyDistance field; 
/// nil::marshalling::units::setMeters(field, 1.2345);
/// std::cout << "distance in 1/10 of mm:" << field.value() << std::endl; // prints 12345
/// std::cout << "distance in mm" << nil::marshalling::units::get_millimeters<double>(field); // prints 1234.5
/// std::cout << "distance in cm" << nil::marshalling::units::get_centimeters<double>(field); // prints 123.45
/// @endcode
/// By default, When @ref nil::marshalling::types::IntValue field is constructed, the inner
/// value is constructed to be 0. However, the field definition may use
/// @ref nil::marshalling::option::default_num_value option to specify some other value
/// @code
/// // definition of integral field
/// using MyIntField = 
///     nil::marshalling::types::IntValue<
///         MyFieldBase, // base class for all the fields, defined by the protocol definition library
///         std::uint16_t,
///         nil::marshalling::option::default_num_value<25>
///     >;
///
/// MyIntField field;
/// assert(field.value() == 25);
/// @endcode
///
/// @subsection page_use_prot_fields_enum_value Enum value fields_type
/// The @b enum values are defined using @ref nil::marshalling::types::EnumValue class. It
/// is very similar to @ref page_use_prot_fields_int_value. The main difference,
/// that second template parameter as well as inner @b value_type type is @b enum.
/// The @b enum can be scoped (enum class) or regular (just enum).
/// @code
/// enum class SomeEnumVal : std::uint8_t
/// {
///     Val1,
///     Val2,
///     Val3,
///     NumOfValues
/// };
///
/// using SomeEnumField = 
///     nil::marshalling::types::EnumValue<
///         MyFieldBase,
///         SomeEnumVal,
///         nil::marshalling::option::valid_num_value_range<0, (int)SomeEnumVal::NumOfValues - 1>,
///         nil::marshalling::option::default_num_value<(int)SomeEnumVal::Val3>
///     >;
///
/// SomeEnumField field;
/// assert(field.value() == SomeEnumVal::Val3); // initialised by default to Val3;
/// field.value() = SomeEnumVal::Val2;
/// @endcode 
///
/// @subsection page_use_prot_fields_bitmask_value Bitmask value fields_type
/// Bitmasks (or bitsets) are also numeric values where every bit has separate,
/// independent meaning. Such fields are defined using @ref nil::marshalling::types::BitmaskValue
/// class. 
/// @code
/// struct MyBitmask : public 
///     nil::marshalling::types::BitmaskValue<
///         MyFieldBase, 
///         nil::marshalling::option::fixed_length<1>,
///         nil::marshalling::option::bitmask_reserved_bits<0x2, 0> // Second bit is reserved and must be 0
///     >
/// {
///     ...
/// };
/// @endcode
/// The field definition will use @ref nil::marshalling::option::fixed_length option in
/// order to specify its serialization length. The inner @b value_type type will
/// be calculated automatically and defined as one of the unsigned types: 
/// @b std::uint8_t, @b std::uint16_t, @b std::uint32_t, or @b std::uint64_t.
/// The usage of @ref nil::marshalling::option::bitmask_reserved_bits option will mark
/// certain bits as "reserved". It influences only validity check functionality
/// (see @ref nil::marshalling::types::BitmaskValue::valid()). If any of the reserved bits
/// doesn't have an expected value, the call to @b valid() member function will
/// return @b false.
///
/// The bitmask field definition is also expected to use @ref MARSHALLING_BITMASK_BITS()
/// and @ref MARSHALLING_BITMASK_BITS_ACCESS() macros to provide names for the bits
/// and generate convenience access function. If bit names are sequential, i.e. start
/// from bit @b 0, and go up without any holes in the middle, then single
/// @ref MARSHALLING_BITMASK_BITS_SEQ() macro can be used instead achieving the same
/// effect.
/// @code
/// struct MyBitmask : public
///     nil::marshalling::types::BitmaskValue<
///         MyFieldBase, 
///         nil::marshalling::option::fixed_length<1>,
///         nil::marshalling::option::bitmask_reserved_bits<0x2, 0> // Second bit is reserved and must be 0
///     >
/// {
///     MARSHALLING_BITMASK_BITS(first, third=2, fourth, fifth, sixth, seventh, eighth);
///     MARSHALLING_BITMASK_BITS_ACCESS(first, third, fourth, fifth, sixth, seventh, eighth);
/// }
/// @endcode
/// is equivalent to defining:
/// @code
/// struct MyBitmask : public
///     nil::marshalling::types::BitmaskValue<
///         MyFieldBase, 
///         nil::marshalling::option::fixed_length<1>,
///         nil::marshalling::option::bitmask_reserved_bits<0x2, 0>
///     >
/// {
///     enum BitIdx 
///     {
///         BitIdx_first,
///         BitIdx_third=2,
///         BitIdx_fourth,
///         BitIdx_fifth,
///         BitIdx_sixth,
///         BitIdx_seventh,
///         BitIdx_eighth,
///         BitIdx_numOfValues
///     }
///
///     bool getBitValue_first() const { return get_bit_value(BitIdx_first); }
///     void set_bit_value_first(bool val) { set_bit_value(BitIdx_first, val); }
///     bool getBitValue_third() const { ... }
///     void set_bit_value_third(bool val) { ... }
///     bool getBitValue_fourth() const { ... }
///     void set_bit_value_fourth(bool val) { ... }
///     ...
/// }
/// @endcode
/// The generated convenience access functions use existing 
/// @ref nil::marshalling::types::BitmaskValue::get_bit_value() and
/// @ref nil::marshalling::types::BitmaskValue::set_bit_value() member functions.
///
/// It is also possible to set multiple bits at the same time by accessing 
/// the stored value directly
/// @code
/// MyBitmask field;
/// field.value() = 0x81; // Setting first and eighth bits
/// @endcode
///
/// @subsection page_use_prot_fields_bitfield Bitfield fields_type
/// Many communication protocols try to pack multiple independent values into
/// a one or several bytes to save traffic on I/O link. For example RS-232 serial port
/// configuration may be defined as following:
///
/// 3 Bits to configure baud rate:
/// |Baud Rate | Serialisation value|
/// |:--------:|:------------------:|
/// | 9600     | 0                  |
/// | 14400    | 1                  |
/// | 19200    | 2                  |
/// | 28800    | 3                  |
/// | 38400    | 4                  |
/// | 57600    | 5                  |
/// | 115200   | 6                  |
///
/// 2 Bits to configure parity:
/// |Parity    | Serialisation value|
/// |:--------:|:------------------:|
/// | None     | 0                  |
/// | Odd      | 1                  |
/// | Even     | 2                  |
///
/// 2 Bits to configure stopBits:
/// |Stop Bits     | Serialisation value |
/// |:------------:|:-------------------:|
/// | One          | 0                   |
/// | One and half | 1                   |
/// | Two          | 2                   |
///
/// 2 Bits to configure flow control:
/// |Flow Control  | Serialisation value |
/// |:------------:|:-------------------:|
/// | None         | 0                   |
/// | Hardware     | 1                   |
/// | Software     | 2                   |
///
/// The field definition will use @ref nil::marshalling::types::Bitfield and probably look similar to code below
/// @code
/// enum class Baud {...}
/// enum class Parity {...}
/// enum class StopBits {...}
/// enum class FlowControl {...}
///
/// struct SerialConfigField : public 
///     nil::marshalling::types::Bitfield<
///         MyFieldBase, 
///         std::tuple<
///             nil::marshalling::types::EnumValue<MyFieldBase, Baud, nil::marshalling::option::fixed_bit_length<3> >,
///             nil::marshalling::types::EnumValue<MyFieldBase, Parity, nil::marshalling::option::fixed_bit_length<2> >,
///             nil::marshalling::types::EnumValue<MyFieldBase, StopBits, nil::marshalling::option::fixed_bit_length<2> >,
///             nil::marshalling::types::EnumValue<MyFieldBase, FlowControl, nil::marshalling::option::fixed_bit_length<2> >,
///             nil::marshalling::types::IntValue<MyFieldBase, std::uint8_t, nil::marshalling::option::fixed_bit_length<7> >
///         >
///     >
/// {
///     MARSHALLING_FIELD_MEMBERS_ACCESS(baud, parity, stopBits, flowControl, reserved);
/// }
/// @endcode
/// All the member fields of the @ref nil::marshalling::types::Bitfield are stored internally
/// as @b std::tuple, as the result the inner @b value_type of such field is
/// @b std::tuple of all member fields and call to @ref nil::marshalling::types::Bitfield::value()
/// member function will give an access to it. 
///
/// The field definition is expected to use @ref MARSHALLING_FIELD_MEMBERS_ACCESS() macro,
/// which will generate @b FieldIdx enum as well as convenience access member 
/// functions. The code becomes equivalent to:
/// @code
/// struct SerialConfigField : public 
///     nil::marshalling::types::Bitfield<
///         MyFieldBase, 
///         std::tuple<
///             nil::marshalling::types::EnumValue<MyFieldBase, Baud, nil::marshalling::option::fixed_bit_length<3> >,
///             nil::marshalling::types::EnumValue<MyFieldBase, Parity, nil::marshalling::option::fixed_bit_length<2> >,
///             nil::marshalling::types::EnumValue<MyFieldBase, StopBits, nil::marshalling::option::fixed_bit_length<2> >,
///             nil::marshalling::types::EnumValue<MyFieldBase, FlowControl, nil::marshalling::option::fixed_bit_length<2> >,
///             nil::marshalling::types::IntValue<MyFieldBase, std::uint8_t, nil::marshalling::option::fixed_bit_length<7> >
///         >
///     >
/// {
///     // Access indices for member fields
///     enum FieldIdx {
///         FieldIdx_baud,
///         FieldIdx_parity,
///         FieldIdx_stopBits,
///         FieldIdx_flowControl,
///         FieldIdx_reserved,
///         FieldIdx_numOfValues
///     };
/// 
///     // Accessor to "baud" field
///     auto field_baud() -> decltype(std::get<FieldIdx_baud>(value()))
///     {
///         return std::get<FieldIdx_baud>(value());
///     }
///
///     // Accessor to const "baud" field
///     auto field_baud() const -> decltype(std::get<FieldIdx_baud>(value()))
///     {
///         return std::get<FieldIdx_baud>(value());
///     }
///
///     // Accessor to "parity" field
///     auto field_parity() -> decltype(std::get<FieldIdx_parity>(value()))
///     {
///         return std::get<FieldIdx_parity>(value());
///     }
///
///     // Accessor to const "parity" field
///     auto field_parity() const -> decltype(std::get<FieldIdx_parity>(value()))
///     {
///         return std::get<FieldIdx_parity>(value());
///     }
///
///     ... // and so on for all other member fields
/// }
/// @endcode
/// Accessing the member field value in such setup, such as "baud" may look
/// like this:
/// @code
/// SerialConfigField configField;
/// configField.field_baud().value() = Baud::Val_115200;
/// @endcode
/// 
/// @subsection page_use_prot_fields_bundle Bundle fields_type
/// There are cases when multiple independent fields need to be bundled into
/// a single field and expose the required interface of reading, writing,
/// calculating length, checking field's contents validity, and bringing field's
/// value into a consistent state. It may be required
/// when a message contains sequence (see @ref page_use_prot_fields_array_list) 
/// of such bundles/structs. The Marshalling library provides @ref nil::marshalling::types::Bundle
/// field for this purpose. It is quite similar to @ref nil::marshalling::types::Bitfield described
/// earlier. The difference is that every member field
/// doesn't specify any length in bits, just bytes. For example:
/// @code
/// enum SomeEnum : std::uint8_t
/// {
///     SomeEnum_Value1,
///     SomeEnum_Value2,
///     SomeEnum_Value3,
///     ...
/// }
///
/// struct MyBundle : public
///     nil::marshalling::types::Bundle<
///         MyFieldBase,
///         std::tuple<
///             nil::marshalling::types::IntValue<MyFieldBase, std::int16_t> // 2 bytes int value
///             nil::marshalling::types::EnumValue<MyFieldBase, SomeEnum>, // 1 byte enum value
///             nil::marshalling::types::BitmaskValue<MyFieldBase, nil::marshalling::option::fixed_length<1> > // 1 byte bitmask
///         >
///     >
/// {
///     MARSHALLING_FIELD_MEMBERS_ACCESS(member1, member2, member3);
/// };
/// @endcode
/// Just like with @ref page_use_prot_fields_bitfield, the inner @b value_type type
/// of such field is a @b std::tuple of member fields, and usage of 
/// @ref MARSHALLING_FIELD_MEMBERS_ACCESS() has exactly the same effect, i.e. generates
/// inner @b FieldIdx enum and convenience access member functions:
/// @code
/// struct MyBundle : public
///     nil::marshalling::types::Bundle<
///         MyFieldBase,
///         std::tuple<
///             nil::marshalling::types::IntValue<MyFieldBase, std::int16_t> // 2 bytes int value
///             nil::marshalling::types::EnumValue<MyFieldBase, SomeEnum>, // 1 byte enum value
///             nil::marshalling::types::BitmaskValue<MyFieldBase, nil::marshalling::option::fixed_length<1> > // 1 byte bitmask
///         >
///     >
/// {
///     enum FieldIdx
///     {
///         FieldIdx_member1,
///         FieldIdx_member2,
///         FieldIdx_member3,
///         FieldIdx_numOfValues
///     };
///
///     // Accessor to "member1" field
///     auto field_member1() -> decltype(std::get<FieldIdx_member1>(value()))
///     {
///         return std::get<FieldIdx_member1>(value());
///     }
///
///     // Accessor to const "baud" field
///     auto field_member1() const -> decltype(std::get<FieldIdx_member1>(value()))
///     {
///         return std::get<FieldIdx_member1>(value());
///     }
///
///     // Accessor to "parity" field
///     auto field_member2() -> decltype(std::get<FieldIdx_member2>(value()))
///     {
///         return std::get<FieldIdx_member2>(value());
///     }
///
///     ...
/// };
/// @endcode
///
/// @subsection page_use_prot_fields_array_list Array List fields_type
/// Some communication protocols may define messages that transmit sequence
/// of similar fields and/or raw data buffers. To make it easier to handle, the
/// Marshalling library provides nil::marshalling::types::array_list field which provide a required
/// interface to properly handle such sequences of data. It supports a
/// sequence of raw bytes
/// @code
/// using MySimpleList = 
///     nil::marshalling::types::array_list<
///         MyFieldBase,
///         std::uint8_t // raw byte type as second template parameter
///     >;
/// @endcode
/// as well as using sequence of any fields defined in nil::marshalling::field namespace
/// @code
/// using MyComplexList = 
///     nil::marshalling::types::array_list<
///         MyFieldBase,
///         MyBundle // Complex bundle field, defined in previous section 
///     >;
/// @endcode
/// The @b default storage type (inner @b value_type type) of these fields is
/// @b std::vector of specified type, i.e. it is @b std::vector<std::uint8_t>
/// in case of @b MySimpleList and @b std::vector<MyBundle> in case of
/// @b MyComplexList. Such default storage type may be unsuitable to certain
/// applications, especially for bare-metal ones. The @b Marshalling library allows
/// changing it using extra options. The protocol definition is expected to
/// provide a way to pass extra options to such fields. It is explained in
/// @ref page_use_prot_fields_customisation section below in more detail.
///
/// Please pay attention, that in case of non-raw data lists, the inner @b std::vector
/// contains fields, not values. As the result access to the stored values 
/// may require a bit of extra function calls:
/// @code
/// MyComplexList list;
/// auto& storageVec = list.value(); // access to std::vector<MyBundle>
/// storageVec.resize(1);
/// auto& firstBundle = storageVec[0]; // access to first MyBundle element
/// auto& firstMember1 = firstBundle.field_member1(); // access to "member1" member of first bundle
/// auto mem1Value = firstMember1.value(); // get the actual value of "member1"
/// @endcode
/// Some protocols may define fixed size lists. In such case lists are defined
/// with usage of @ref nil::marshalling::option::sequence_fixed_size option.
/// @code
/// using MyList = 
///     nil::marshalling::types::array_list<
///         MyFieldBase,
///         nil::marshalling::types::IntValue<MyFieldBase, std::uint16_t>,
///         nil::marshalling::option::sequence_fixed_size<4>
///     >;
/// @endcode
/// Usage of this option just ensures right amount of elements "on the wire" after
/// the field is serialized, but it doesn't automatically resize inner
/// storage vector.
/// @code
/// MyList field;
/// assert(field.value().empty()); // vector is empty upon construction
/// @endcode
///
/// @subsection page_use_prot_fields_string String fields_type
/// Many protocols have to transfer strings. They are defined using
/// @ref nil::marshalling::types::String field.
/// @code
/// using MyString = nil::marshalling::types::String<MyFieldBase>;
/// @endcode
/// It is very similar to nil::marshalling::types::array_list
/// it terms of value storage, read/write operations, and supported options.
/// By default the value is stored as 
/// <a href="http://en.cppreference.com/w/cpp/string/basic_string">std::string</a>.
/// @code
/// MyString myStr;
/// auto& myStrStorage = myStr.value(); // reference to std::string.
/// @endcode
/// However, there are options that can modify this default behaviour. The
/// protocol definition classes are expected to provide a way to pass extra
/// application specific options to the string field definition. It is explained
/// in more detail in @ref page_use_prot_fields_customisation section below.
///
/// Also similar to @ref page_use_prot_fields_array_list, fixed length strings
/// are defined using @ref nil::marshalling::option::sequence_fixed_size option, and just
/// like with lists it doesn't automatically resize inner string, just ensures
/// right amount of characters "on the wire" when field is serialized.
/// @code
/// using MyFixedString = 
///     nil::marshalling::types::String<
///         MyFieldBase,
///         nil::marshalling::option::sequence_fixed_size<32>
///     >;
///
/// MyFixedString field;
/// assert(field.value().empty());
/// @endcode
///
/// @subsection page_use_prot_fields_fp_value Floating Point value fields_type
/// Floating point value fields are defined using @ref nil::marshalling::types::FloatValue
/// They are very similar to 
/// @ref page_use_prot_fields_int_value, but use @b float or @b double as its 
/// internal storage type. They abstract the IEEE 754 floating point 
/// values, which are serialized "as is" with either big or little endian
/// encoding. The floating point value fields also support 
/// the same scaling and units conversion just like @ref page_use_prot_fields_int_value.
///
/// @subsection page_use_prot_fields_optional Optional fields_type
/// Some protocols may define optional fields, which may exist or be missing
/// based on information recorded in other fields. For example there is a
/// "flags" bitmask field which specifies whether the following field exists or
/// missing. The optional field may also be tentative, i.e. if there is enough
/// data in the input buffer it exists, and missing otherwise. The Marshalling
/// library provides @ref nil::marshalling::types::Optional which is a mere wrapper around
/// other fields and provides an ability to set the optional state of the field.
/// @code
/// using OptField = 
///     nil::marshalling::types::Optional<
///         nil::marshalling::types::IntValue<MyFieldBase, std::int32_t>
///     >;
/// @endcode
/// The default mode of such field is "tentative".
/// @code
/// OptField field;
/// assert(field.is_tentative());
/// @endcode
/// The default mode can be changed using @ref nil::marshalling::option::exists_by_default
/// or @ref nil::marshalling::option::missing_by_default options. For example
/// @code
/// using ExistingOptField = 
///     nil::marshalling::types::Optional<
///         nil::marshalling::types::IntValue<MyFieldBase, std::int32_t>,
///         nil::marshalling::option::exists_by_default
///     >;
///
/// ExistingOptField field;
/// assert(field.does_exist());
/// @endcode
/// @b NOTE, that inner @b value_type of such field is wrapped actual field and
/// both @ref nil::marshalling::types::Optional::value() and @ref nil::marshalling::types::Optional::field()
/// member functions allow to access it. For example:
/// @code
/// OptField field;
/// auto& innerField = field.field(); // or call field.value()
/// innerField.value() = 1234;
/// field.set_exists();
/// @endcode
///
/// @subsection page_use_prot_fields_variant Variant fields_type
/// Some protocols may require usage of heterogeneous fields or lists of 
/// heterogeneous fields, i.e. the ones that can be of multiple types. Good example
/// would be a list of @b properties, where every property is a key/value pair. The
/// key is a numeric ID of the property, while value can be a numeric field of
/// any length or a string one. Such fields are defined using 
/// @ref nil::marshalling::types::Variant class. It is very similar to @ref
/// page_use_prot_fields_bundle, but serves as one big union of provided member
/// fields, i.e. only one can be used at a time. These fields are quite rare
/// and if your protocol defines one, please read @ref sec_field_tutorial_variant
/// tutorial on how to define one, it will explain how to use it as well.
///
/// @subsection page_use_prot_fields_customisation Application Specific Customisation of fields_type
/// The @b Marshalling library provides multiple options to modify default behaviour
/// of field classes. Many of them modify the way how the field is (de)serialized.
/// Such options are expected to be used in actual protocol definition code. However,
/// there are also options that modify used data structures or field's behaviour. Such
/// options are application specific, and the protocol definition is expected
/// to provide a way on delivering such options to fields definitions. The recommended
/// way for the protocol definition is to have separate struct called @b DefaultOptions
/// which defines all the relevant extension options as its inner types. For example,
/// The message definition may look like this:
/// @code
/// #pragma once
/// #include <nil/marshalling/marshalling.h"
///
/// #include "MyFieldBase.h" // Defines MyFieldBase common base class for all the fields
/// #include "DefaultOptions.h" // Defines DefaultOptions struct
///
/// namespace my_protocol
/// {
/// 
/// namespace message
/// {
///
/// template <typename TOpt = DefaultOptions>
/// struct Message1Fields
/// {
///     using field1 = ...;
///     using field2 = ...
///     using field3 = 
///         nil::marshalling::types::String<
///             MyFieldBase,
///             typename TOpt::message::Message1Fields::field3 // Extra option(s) 
///         >
///
///     // bunding type
///     using All = 
///         std::tuple<
///             field1,
///             field2,
///             field3
///         >;
/// };
///
/// template <typename TBase, typename TOpt = DefaultOptions>
/// class Message1 : public 
///     nil::marshalling::MessageBase<
///         TBase, 
///         nil::marshalling::option::static_num_id_impl<MsgId_Message1>,
///         nil::marshalling::option::fields_impl<Message1Fields<TOpt>::All>, // using fields with extra options
///         nil::marshalling::option::msg_type<Message1<TBase, TOpt> >
///     >
/// {
///     // Provide names for the fields
///     MARSHALLING_MSG_FIELDS_ACCESS(value1, value2, value3);
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// The inner structure of @b DefaultOptions struct is not important, but 
/// the recommended practice is to resemble the scope of fields. It may look 
/// like this
/// @code
/// namespace my_protocol
/// {
/// struct DefaultOptions
/// {
///     struct message
///     {
///         struct Message1Fields
///         {
///             using field1 = nil::marshalling::option::empty_option; // no extra functionality by default
///             using field2 = nil::marshalling::option::empty_option; // no extra functionality by default
///             using field3 = nil::marshalling::option::empty_option; // no extra functionality by default
///         };
///     };
/// };
/// } // my_protocol
/// @endcode
/// The application is expected to provide its own options describing 
/// struct / class if needed. The easiest way is to extend provided @b DefaultOptions
/// and override selected types. For example
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         struct Message1Fields : public my_protocol::DefaultOptions::message::Message1Fields
///         {
///             using field3 = nil::marshalling::option::fixed_size_storage<32>;
///         };
///     };
/// };
/// @endcode
/// The Definition of the message(s) may look like this:
/// @code
/// using MyMessage1 = my_protocol::Message1<MyMessage, MyOptions>;
/// @endcode
/// If there is a need to pass more than one extra option to a field, these
/// options can be bundled together is @b std::tuple.
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         struct Message1Fields : public my_protocol::DefaultOptions::message::Message1Fields
///         {
///             using field3 = std::tuple<..., ...>;
///         };
///     };
/// };
/// @endcode
///
/// @subsubsection page_use_prot_fields_customisation_seq Customisation for Lists and Strings
/// As was already mentioned earlier the default storage type (@b value_type) of
/// @ref page_use_prot_fields_array_list is @b std::vector, while default
/// storage type for @ref page_use_prot_fields_string is @b std::string. These
/// types are suitable for most of C++ applications, but may be unsuitable for
/// bare-metal embedded platforms. That why the protocol definition @b must allow
/// additional customisation of such fields. 
///
/// The @b Marshalling library provides
/// multiple options to change the default storage type. 
/// There is @ref nil::marshalling::option::fixed_size_storage option. When passed to the
/// @ref nil::marshalling::types::array_list or @ref nil::marshalling::types::String, it changes the
/// default storage type to be @ref nil::marshalling::container::static_vector or
/// @ref nil::marshalling::processing::StaticString respectively. These types expose the same
/// public API as @b std::vector or @b std::string, but use pre-allocated 
/// storage area (as their private member) to store the elements / characters.
/// Note, that the @ref nil::marshalling::option::fixed_size_storage option has a template
/// parameter, which specify number of elements (not necessarily bytes) to be
/// stored. If the field definition already uses @ref nil::marshalling::option::sequence_fixed_size
/// option to specify that number of elements is fixed, there is 
/// @ref nil::marshalling::option::sequence_fixed_size_use_fixed_size_storage
/// option which has the same effect of forcing @ref nil::marshalling::container::static_vector
/// or @ref nil::marshalling::processing::StaticString to be storage types, but does not
/// require repeating specification of storage area size.
/// For example, if message type is defined to use provided @b DefaultOptions, then
/// the storage type of @b field3 will be @b std::string
/// @code
/// using MyMessage1 = my_protocol::Message1<MyMessage>;
/// MyMessage1 msg;
/// std::string& field3Str = msg.field_value3().value();
/// @endcode
/// However, if message type is defined to used described earlier @b MyOptions, then
/// the storage type of @b field3 will be @ref nil::marshalling::processing::StaticString
/// @code
/// using MyMessage1 = my_protocol::Message1<MyMessage, MyOptions>;
/// MyMessage1 msg;
/// nil::marshalling::container::static_string<32>& field3Str = msg.field_value3().value();
/// @endcode
/// NOTE, that using default @b std::vector / @b std::string or provided
/// @ref nil::marshalling::container::static_vector / @ref nil::marshalling::processing::StaticString will involve
/// copying of the data to these storage areas during the @b read operation. If
/// the input buffer is contiguous, i.e the pointer to the last element is @b always
/// greater than pointer to the first one (not some kind of circular buffer), then
/// to copying of the data may be avoided by using @ref nil::marshalling::option::orig_data_view
/// option. The option will change the default storage types to be 
/// @ref nil::marshalling::processing::ArrayView or @ref nil::marshalling::processing::StringView. @b NOTE, that
/// passing @ref nil::marshalling::option::orig_data_view option to @ref nil::marshalling::types::array_list
/// is possible only if it is list of raw data (@b std::uint8_t is used as element type).
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         struct Message1Fields : public my_protocol::DefaultOptions::message::Message1Fields
///         {
///             using field3 = nil::marshalling::option::orig_data_view;
///         };
///     };
/// };
/// @endcode
///
/// If default standard @b std::vector / @b std::string or all the provided 
/// by the @b Marshalling library storage type are
/// not good enough, it is possible to specify custom storage type
/// using @ref nil::marshalling::option::custom_storage_type option. For example:
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         struct Message1Fields : public my_protocol::DefaultOptions::message::Message1Fields
///         {
///             using field3 = 
///                 nil::marshalling::option::custom_storage_type<
///                     boost::container::pmr::string
///                 >;
///         };
///     };
/// };
/// @endcode
///
/// @subsubsection page_use_prot_fields_customisation_other Customisation for Other fields_type
/// While allowing extra customisation for fields like @b list or @b string is
/// a <b>"must have"</b> feature of the protocol definition, it may also allow
/// additional customisation of other fields as well. For example, let's assume
/// that @b field1 of previously mentioned @b Message1 is a numeric field, that
/// defined the following way:
/// @code
/// #pragma once
/// #include <nil/marshalling/marshalling.h"
///
/// #include "MyFieldBase.h" // Defines MyFieldBase common base class for all the fields
/// #include "DefaultOptions.h" // Defines DefaultOptions struct
///
/// namespace my_protocol
/// {
/// 
/// namespace message
/// {
///
/// template <typename TOpt = DefaultOptions>
/// struct Message1Fields
/// {
///     using field1 = 
///         nil::marshalling::types::IntValue<
///             MyFieldBase,
///             std::uint8_t,
///             typename TOpt::message::Message1Fields::field1, // Extra options 
///             nil::marshalling::option::default_num_value<10>,
///             nil::marshalling::option::valid_num_value_range<10, 20>
///         >;
///     ...
/// };
///
/// template <typename TBase, typename TOpt = DefaultOptions>
/// class Message1 : public 
///     nil::marshalling::MessageBase<
///         TBase, 
///         nil::marshalling::option::static_num_id_impl<MsgId_Message1>,
///         nil::marshalling::option::fields_impl<Message1Fields<TOpt>::All>, // using fields with extra options
///         nil::marshalling::option::msg_type<Message1<TBase, TOpt> >
///     >
/// {
///     ...
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// If not other options are passed as @b message::Message1Fields::field1 inner
/// type of application specific options struct / class, then the inner value of 
/// @b field1 will be initialised to @b 10 upon construction and the range of
/// valid values will be <b>[10, 20]</b>. Such default settings may be modified
/// using various options. For example, making the value to be initialised to @b 5 and
/// adding it to valid values may look like this:
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         struct Message1Fields : public my_protocol::DefaultOptions::message::Message1Fields
///         {
///             using field1 = 
///                 std::tuple<
///                     nil::marshalling::option::default_num_value<5>,
///                     nil::marshalling::option::ValidNumValue<5>
///                 >;
///         };
///     };
/// };
/// @endcode
/// After these extra options are passed to the field's definition it becomes
/// equivalent to 
/// @code
///     using field1 = 
///         nil::marshalling::types::IntValue<
///             MyFieldBase,
///             std::uint8_t,
///             nil::marshalling::option::default_num_value<5>, // overrides default value 10 defined below
///             nil::marshalling::option::ValidNumValue<5>, // added to previously defined range [10, 20]
///             nil::marshalling::option::default_num_value<10>,
///             nil::marshalling::option::valid_num_value_range<10, 20>
///         >;
/// @endcode
/// @b NOTE that @b Marshalling library processes all the options @b bottom-up, i.e.
/// starts with @b nil::marshalling::option::valid_num_value_range<10, 20> (which records initial
/// valid range [10, 20]), then processes @b nil::marshalling::option::default_num_value<10>
/// (which records default value to be 10), then processes @b nil::marshalling::option::ValidNumValue<5>
/// (which @b adds value 5 to the existing valid ranges), then processes
/// @b nil::marshalling::option::default_num_value<5> (which changes the default value to be 5).
///
/// In case the application needs to override originally defined valid range(s) of
/// the field, it can use @ref nil::marshalling::option::valid_ranges_clear
/// option, which will clear all
/// previously defined valid ranges and will start accumulating them anew. For
/// example:
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         struct Message1Fields : public my_protocol::DefaultOptions::message::Message1Fields
///         {
///             using field1 = 
///                 std::tuple<
///                     nil::marshalling::option::default_num_value<5>, // change the default value
///                     nil::marshalling::option::ValidNumValue<5>, // add 5 to valid ranges of [40, 50]
///                     nil::marshalling::option::valid_num_value_range<40, 50>, // new range
///                     nil::marshalling::option::valid_ranges_clear // clear the default ranges
///                 >;
///         };
///     };
/// };
/// @endcode
/// Additional option that may be quite useful is @ref nil::marshalling::option::fail_on_invalid.
/// It causes the @b read operation to fail with provided error status when
/// read value is not valid (@b valid() member function returns @b false).
///
/// There may be other useful options, which are not covered by this tutorial,
/// please open reference page of a required @b field class for the list of
/// supported options and read their documentation for more detail.
///
/// @section page_use_prot_transport Transport Framing
/// In addition to definition of the messages and their contents, every 
/// communication protocol must ensure that the message is successfully delivered 
/// over the I/O link to the other side. The serialized message payload must
/// be wrapped in some kind of transport information prior to being sent and 
/// unwrapped on the other side when received. The @b Marshalling protocol defines
/// multiple so called @b layers (defined in @b nil::marshalling::protocol namespace).
/// The transport framing will be defined using those @b layer classes and will
/// probably be called @b ProtocolStack. Its definition is expected to
/// looke something like this:
/// @code
/// namespace my_protocol
/// {
///
/// template <
///     typename TMessage, // common interface class defined by the application
///     typename TInputMessages = all_messages_type<TMessage>, // Input messages that need to be recognised
///     typename TAllocationOptions = nil::marshalling::option::empty_option, // Extra options for nil::marshalling::protocol::MsgIdLayer
///     typename TPayloadOptions = nil::marshalling::option::empty_option // Extra options for payload storage
/// >
/// struct ProtocolStack : public 
///     MySyncPrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions> 
/// {
///     MARSHALLING_PROTOCOL_LAYERS_ACCESS(...);
/// };
///
/// } // namespace my_protocol
/// @endcode
/// The first template parameter (@b TMessage) is common message interface class desribed
/// earlier in @ref page_use_prot_interface section.
/// 
/// The second template parameter (@b TInputMessages) is @b std::tuple of input
/// messages that @b read operation is expected to recognise. The message classes
/// must be sorted by the ascending order of message IDs. The protocol definition
/// is also expected to define @b all_messages_type tuple which lists all the protocol
/// messages, which can be used as reference.
///
/// The third template parameter (@b TAllocationOptions) is extra option(s)
/// (bundled in @b std::tuple if more than one) to be passed to 
/// @ref nil::marshalling::protocol::MsgIdLayer class which is responsible for message
/// allocation. By default the message object is dynamically allocated, it is 
/// possible to modify such behaviour by using @ref nil::marshalling::option::in_place_allocation
/// option. It will be explained in more detail further below.
///
/// The fourth template parameter (@b TPayloadOptions) is irrelevant in
/// most cases. It has a meaning only when transport wrapping values are cached
/// for further analysis. It will also be explained in more detail further below.
///
/// @b NOTE, that @b ProtocolStack definition is actually an alias to one
/// of the classes from @ref nil::marshalling::protocol namespace. To get a detailed
/// information on available public API please reference to one of them, for
/// example @ref nil::marshalling::protocol::SyncPrefixLayer.
///
/// @subsection page_use_prot_transport_read Reading Transport Framing and Message Payload
/// Below is an example of how to implement data processing loop, which parses
/// the raw bytes in the provided input buffer, creates appropriate message 
/// message object and dispatches it to the right handler.
/// @code
/// // Alias to my_protocol::ProtocolStack
/// using ProtStack = my_protocol::ProtocolStack<MyMessage>
///
/// ProtStack protStack; // Protocol stack object
/// MyHandler handler; // handler object
///
/// // Receives input buffer and its size and returns number of consumed bytes
/// std::size_t processInput(const std::uint8_t* buf, std::size_t len)
/// {
///     std::size_t consumed = 0U;
///     // Processing loop
///     while (consumed < len) {
///         // Smart pointer to the message object.
///         ProtStack::msg_ptr_type msgPtr;
///
///         // type of the message interface class
///         using msg_type = ProtStack::msg_ptr_type::element_type;
///     
///         // Get the iterator for reading
///         auto begIter = nil::marshalling::readIteratorFor<msg_type>(buf + consumed);
///         auto iter = begIter;
///
///         // Do the read
///         auto es = protStack.read(msgPtr, iter, len - consumed);
///         if (es == nil::marshalling::ErrorStatus::not_enough_data) {
///             break; // Not enough data in the buffer, stop processing
///         } 
///     
///         if (es == nil::marshalling::ErrorStatus::protocol_error) {
///             // Something is not right with the data, remove one character and try again
///            ++consumed;
///             continue;
///         }
///
///         if (es == nil::marshalling::ErrorStatus::success) {
///             assert(msgPtr); // If read is successful, msgPtr is expected to hold a valid pointer
///             msgPtr->dispatch(handler); // Dispatch message for handling
///         }
///
///         // The iterator for reading has been advanced, update the difference
///         consumed += std::distance(begIter, iter);
///     }
///
///     // Report how many bytes have been consumed from the buffer
///     return consumed;
/// }
/// @endcode
/// Please pay attention to the following detail:
/// @li The first template parameter passed to @b my_protocol::ProtocolStack is
///     @b MyMessage interface class defined earlier in @ref page_use_prot_interface
///     section.
/// @li The protocol stack type defines type of the smart pointer that 
///     holds message object that was allocation during @b read operation:
///     @code
///     ProtStack::msg_ptr_type msgPtr;
///     @endcode
/// @li The @b ProtStack::msg_ptr_type is a variant of
///     <a href="http://en.cppreference.com/w/cpp/memory/unique_ptr">unique_ptr</a>.
///     As the result the type of the interface can be retrieved using internal
///     type @b element_type. It is expected to be the same as @b MyMessage
///     common interface class.
///     @code
///     using msg_type = ProtStack::msg_ptr_type::element_type;
///     @endcode
/// @li During the read operation, when message object has been successfully allocated,
///     the message payload will be read by invoking the @ref nil::marshalling::Message::read()
///     member function. It means that common message interface class must support
///     polymorphic read (see @ref page_use_prot_interface_read).
///     It means that the iterator used 
///     for reading needs to be convertible to @ref nil::marshalling::Message::read_iterator. It
///     can be achieved by using @ref nil::marshalling::read_iterator_for() template function,
///     which will initialise and return appropriate iterator type. Another 
///     possible way of allocating the iterator can be as following:
///     @code
///     msg_type::read_iterator iter = buf + consumed;
///     @endcode
/// @li After the read operation is determined to be successful, the @b msgPtr
///     holds dynamically allocated message object. The dispatching of the
///     message for the handling is performed using polymorphic @b dispatch().
///     It will require common message interface class to support 
///     @ref page_use_prot_interface_handle. See also @ref page_use_prot_handling
///     section below for more detail on message handling.
///
/// There are protocols when number of input messages is very limited (one or two)
/// such as various types of acknowledgement. To support such case
/// @b read() member function of the @b ProtocolStack supports reception of
/// reference to the real message object (instead of @b msg_ptr_type pointer).
/// @code
/// // Receives input buffer and its size and returns number of consumed bytes
/// std::size_t processInput(const std::uint8_t* buf, std::size_t len)
/// {
///     std::size_t consumed = 0U;
///     // Processing loop
///     while (consumed < len) {
///         // Get the iterator for reading
///         auto begIter = buf + consumed;
///         auto iter = begIter;
///
///         // Do the read
///         using MyAckMsg = my_protocol::AckMsg<MyMessage>;
///
///         MyAckMsg msg; // actual message object
///         auto es = protStack.read(msg, iter, len - consumed);
///         if (es == nil::marshalling::ErrorStatus::not_enough_data) {
///             break; // Not enough data in the buffer, stop processing
///         } 
///
///         if (es == nil::marshalling::ErrorStatus::invalid_msg_id) {
///             // Unexpected message (not AckMsg) has been received, report or handle error
///             ...
///             consumed += std::distance(begIter, iter);
///             continue;
///         }
///     
///         if (es == nil::marshalling::ErrorStatus::protocol_error) {
///             // Something is not right with the data, remove one character and try again
///            ++consumed;
///             continue;
///         }
///
///         if (es == nil::marshalling::ErrorStatus::success) {
///             handler.handle(msg); // Handle message without polymorphic dispatch
///         }
///
///         // The iterator for reading has been advanced, update the difference
///         consumed += std::distance(begIter, iter);
///     }
///
///     // Report how many bytes have been consumed from the buffer
///     return consumed;
/// }
/// @endcode
/// @b NOTE, that in such case there is @b no need for either @ref page_use_prot_interface_read
/// or @ref page_use_prot_interface_handle. In fact, no virtual function call
/// is used in the code above.
///
/// @subsection page_use_prot_transport_msg_alloc Message Object Allocation
/// By default, the message object is dynamically allocated. However, some 
/// applications (especially bare-metal ones) may require something different.
/// The @b Marshalling library has @ref nil::marshalling::option::in_place_allocation option,
/// which may be passed as third template parameter (@b TAllocationOptions)
/// to @b ProtocolStack type definition. It statically allocates (in private data
/// members) storage area, that is capable to store any message object from
/// the @b std::tuple passed as second parameter to @b ProtocolStack type
/// definition. The message allocation is performed using "placement new" operator,
/// which means only one message object can be allocated at a time. The
/// smart pointer holding the message (@b ProtocolStack::msg_ptr_type) is still
/// @b std::unique_ptr, but with custom deleter.
/// 
/// @subsection page_use_prot_transport_generic_msg Using Generic Message
/// In general, if message ID cannot be recognised, then appropriate message object cannot be
/// created and processed, i.e. the reading loop will just discard such input.
/// However, there are applications that serve as some kind of a @b bridge or
/// a @b firewall, i.e. need to recognise and process only limited 
/// number of input messages, all the rest need to be forwarded "as-is" or
/// maybe wrapped in different transport frame before sending it over
/// different I/O link. To help with such task @b Marshalling library provides
/// @ref nil::marshalling::generic_message class. There is also @ref nil::marshalling::option::support_generic_message
/// option that can be passed as third template parameter (@b TAllocationOptions)
/// to the @b ProtocolStack type definition. It will force of creation
/// @ref nil::marshalling::generic_message object when appropriate message object is not found.
/// @code
/// // Define generic message type
/// using MyGenericMessage = nil::marshalling::generic_message<MyMessage>;
///
/// // Limited number of supported messages
/// using MyInputMessages = 
///     std::tuple<
///         my_protocol::Message1<MyMessage>,
///         my_protocol::Message2<MyMessage>
///     >;
///
/// // Protocol stack definition
/// using ProtStack = 
///     my_protocol::ProtocolStack<
///         MyMessage, 
///         MyInputMessages,
///         nil::marshalling::option::support_generic_message<MyGenericMessage>
///     >;
/// @endcode
/// @b NOTE, that @ref nil::marshalling::generic_message has only single field, which
/// is a list of raw data (@ref nil::marshalling::types::array_list). The @b read operation
/// of such field will result in copying the data from input buffer to 
/// internal storage of this field. The @ref nil::marshalling::generic_message
/// class has also other template parameters (except common message interface class).
/// The second template parameter is option(s) that are going to be passed to this
/// nil::marshalling::types::array_list field. If allocated message is @b not going to
/// outlive input buffer, than it may make sense to pass @ref nil::marshalling::option::orig_data_view
/// as second template parameter to @ref nil::marshalling::generic_message.
/// @code
/// using MyGenericMessage = nil::marshalling::generic_message<MyMessage, nil::marshalling::option::orig_data_view>;
/// @endcode
///
/// Also @b note, that it is possible to combine usage of @ref nil::marshalling::option::in_place_allocation
/// and @ref nil::marshalling::option::support_generic_message as the third template parameter to
/// @b ProtocolStack type definition using @b std::tuple bundling.
/// @code
/// using ProtStack = 
///     my_protocol::ProtocolStack<
///         MyMessage, 
///         MyInputMessages,
///         std::tuple<
///             nil::marshalling::option::in_place_allocation,
///             nil::marshalling::option::support_generic_message<MyGenericMessage>
///         >
///     >;
/// @endcode
///
/// @subsection page_use_prot_transport_write Writing Transport Framing and Message Payload
/// The easiest way to implement write functionality is to use the ability of
/// the message object to perform polymorphic write
/// @code
/// ProtStack protStack; // Protocol stack defined in one of previous sections
/// void sendMessage(const MyMessage& msg, std::uint8_t* buf, std::size_t len)
/// {
///     auto writeIter = nil::marshalling::write_iterator_for<MyMessage>(&buf[0]);
///     auto es = protStack.write(msg, writeIter, len);
///     if (es == nil::marshalling::ErrorStatus::success) {
///         ... // Send contents of dataToSend via I/O link
///     }
/// }
/// @endcode
/// In order to support such polymorphic write the common message interface class
/// @b MyMessage has to have the following polymorphic functionality
///
/// @li @ref page_use_prot_interface_write to write the message payload.
/// @li @ref page_use_prot_interface_id_retrieve to write the message ID information.
///
/// In case the transport framing reports size that follows, the support for
/// @ref page_use_prot_interface_length is also recommended. It will be used
/// to write the required value right away. However, if not provided the dummy
/// value (@b 0) will be written at first, then after the write operation is complete,
/// the number of written bytes will be calculated and the previously written 
/// dummy value updated accordingly. @b NOTE, that such update is possible only
/// if iterator used for writing is random-access one. Such update won't be
/// possible. In this case @ref nil::marshalling::ErrorStatus::update_required error status
/// will be returned. It means that the write operation is incomplete, there
/// is a need to perform @b update() call with random-access iterator.
/// For example, let's assume the @ref page_use_prot_interface_length is
/// not supported and <b>std::back_insert_iterator\<std::vector\<std::uint8\> \></b>
/// is passed to @b MyMessage with @ref nil::marshalling::option::write_iterator option.
/// the message object to perform polymorphic write
/// @code
/// ProtStack protStack; // Protocol stack defined in one of previous sections
/// void sendMessage(const MyMessage& msg, std::vector<std::uint8_t>& outBuf)
/// {
///     assert(outBuf.empty()) // Make sure buffer is empty
///     auto writeIter = std::back_inserter(outBuf);
///     auto es = protStack.write(msg, writeIter, outBuf.max_size());
///     if (es == nil::marshalling::ErrorStatus::update_required) {
///         auto updateIter = &outBuf[0];
///         es = protStack.update(updateIter, outBuf.size());
///     }
///         
///     if (es == nil::marshalling::ErrorStatus::success) {
///         ... // Send contents of dataToSend via I/O link
///     }
/// }
/// @endcode
/// Similar scenario of a need to handle @ref nil::marshalling::ErrorStatus::update_required
/// error status may occur when transport framing contains checksum value and
/// output (not random-access) iterator is used. The checksum calculation requires
/// going over the written data to calculate the value. However, it won't be 
/// possible to do right away, the @b update() call must follow.
///
/// The @b ProtocolStack does not require usage of polymorphic
/// write for message serialization all the time. If number of messages being
/// sent is not very high, sometimes it makes sense to avoid adding an ability
/// to support polymorphic write in the common interface. In this case the
/// sending functionality can be implemented using a template function where
/// actual message objects are passed as the parameter:
/// @code
/// template <typename TMsg>
/// void sendMessage(const TMsg& msg)
/// {
///     ...
///     auto es = protStack.write(msg, ...);
///     ...
/// }
/// @endcode
/// Such implementation does not require any polymorphic behaviour from the
/// message object being sent, it takes all the required information from the
/// direct calls to non-virtual @b do_get_id() (see @ref nil::marshalling::MessageBase::do_get_id()) and
/// @b do_length() (see @ref nil::marshalling::MessageBase::do_length()). The payload write is also performed using
/// direct call to @b do_write() (see @ref nil::marshalling::MessageBase::do_write()).
///
/// @subsection page_use_prot_transport_caching Access to Processed Stack fields_type
/// All the examples above do not store the read/written transport fields
/// anywhere. In most cases it is not needed. However, if need arises they can
/// be cached during the read/write operations and accessed later. The @b ProtocolStack
/// also defines @b all_fields_type type which is @b std::tuple of all the fields used by all the
/// layer classes. @n
/// Also, the @b ProtocolStack defines @b read_fields_cached() (see
/// @ref nil::marshalling::protocol::ProtocolLayerBase::read_fields_cached()) and @b write_fields_cached()
/// (see @ref nil::marshalling::protocol::ProtocolLayerBase::write_fields_cached())
/// member functions which are substitutes to normal read() and write(). The first
/// parameter to these functions is reference to the @b all_fields_type bundle
/// object.
/// @code
/// ProtStack::all_fields_type fields;
/// auto es = protStack.read_fields_cached(fields, msgPtr, readIter, bufSize);
/// @endcode
/// The layer class that is responsible to read/write payload data 
/// (see @ref nil::marshalling::protocol::MsgDataLayer) uses @ref nil::marshalling::types::array_list
/// to define a field that will store the payload when "caching" operations are
/// performed. That's where the fourth template parameter (@b TPayloadOptions)
/// to @b ProtocolStack definition comes in play. 
/// In case the the input / output buffer outlives the @b all_fields_type
/// object, consider passing @ref nil::marshalling::option::orig_data_view option as the
/// fourth template parameter to @b ProtocolStack definition, which will pass it to
/// to the field containing the message payload raw data. Otherwise, the 
/// payload part from the read / written buffer will also be copied to storage
/// area of the cached payload field.
///
/// As was mentioned earlier, the protocol stack is defined using so called
/// @b layer classes (defined in @ref nil::marshalling::protocol namespace) by wrapping
/// one another. Access to the appropriate layer may be obtained using a 
/// sequence of calls to @b next_layer() member functions (see
/// @ref nil::marshalling::protocol::ProtocolLayerBase::next_layer()). Alternatively, the protocol stack
/// definition is also expected to use @ref MARSHALLING_PROTOCOL_LAYERS_ACCESS()
/// macro to generate a convenience access functions. For example
/// @code
/// namespace my_protocol
/// {
///
/// template <
///     typename TMessage, // common interface class defined by the application
///     typename TInputMessages = all_messages_type<TMessage>, // Input messages that need to be recognised
///     typename TAllocationOptions = nil::marshalling::option::empty_option, // Extra options for MsgIdLayer
///     typename TPayloadOptions = nil::marshalling::option::empty_option // Extra options for payload storage
/// >
/// struct ProtocolStack : public 
///     MySyncPrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions> 
/// {
///     MARSHALLING_PROTOCOL_LAYERS_ACCESS(payload, id, size, checksum, sync);
/// };
///
/// } // namespace my_protocol
/// @endcode
/// The provided names are used in generation of access member functions with
/// @b layer_ prefix. The code above is equivalent to having the following 
/// member functions defined.
/// @code
/// template <
///     typename TMessage, // common interface class defined by the application
///     typename TInputMessages = all_messages_type<TMessage>, // Input messages that need to be recognised
///     typename TAllocationOptions = nil::marshalling::option::empty_option, // Extra options for MsgIdLayer
///     typename TPayloadOptions = nil::marshalling::option::empty_option // Extra options for payload storage
/// >
/// struct ProtocolStack : public 
///     MySyncPrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions> 
/// {
///     // Access to PAYLOAD layer
///     decltype(auto) layer_payload();
///
///     // Const access to PAYLOAD layer
///     decltype(auto) layer_payload() const;
///
///     // Access to ID layer
///     decltype(auto) layer_id();
///
///     // Const access to ID layer
///     decltype(auto) layer_id() const;
///
///     // Access to SIZE layer
///     decltype(auto) layer_size();
///
///     // Const access to SIZE layer
///     decltype(auto) layer_size() const;
///
///     // Access to CHECKSUM layer
///     decltype(auto) layer_checksum();
///
///     // Const access to CHECKSUM layer
///     decltype(auto) layer_checksum() const;
///
///     // Access to SYNC layer
///     decltype(auto) layer_sync();
///
///     // Const access to SYNC layer
///     decltype(auto) layer_sync() const;
/// };
/// @endcode
/// Then the access to the appropriate layer as as simple as calling appropriate
/// @b layer_*() member function. Once the access is obtained, it is possible to
/// call @b access_cached_field() (see @ref nil::marshalling::protocol::ProtocolLayerBase::access_cached_field())
/// member function to get an access to appropriate field. For example:
/// @code
/// ProtStack protStack; // Protocol stack object
/// ProtStack::all_fields_type fields; // Transport fields
/// auto es = protStack.read_fields_cached(fields, msgPtr, readIter, bufSize);
/// if (es != nil::marshalling::ErrorStatus::success) {
///     ... // handle error
///     return;
/// }
/// std::cout << "SYNC = " << protStack.layer_sync().access_cached_field(fields).value() << '\n';
/// std::cout << "SIZE = " << protStack.layer_size().access_cached_field(fields).value() << '\n';
/// std::cout << "ID = " << protStack.layer_id().access_cached_field(fields).value() << '\n';
/// std::cout << "CHECKSUM = " << protStack.layer_checksum().access_cached_field(fields).value() << std::endl;
/// @endcode
///
/// @section page_use_prot_handling Message Handling
/// When a message is received over I/O link and successfully deserialized, it
/// needs to be dispatched to appropriate handling function. Many
/// developers write quite big (depends on number of messages it needs to handle) 
/// switch statement that checks the ID of the message and calls appropriate 
/// function in the relevant case area. Other developers try to minimise 
/// performance impact by introducing hand written map from message ID to the 
/// handling function. Such approaches are quite inefficient in terms of 
/// execution performance as well as development effort required to introduce 
/// a new message when protocol evolves.
///
/// The @b Marshalling library has a built-in efficient (O(1)) dispatch mechanism, which
/// uses "Double Dispatch" idiom. The @ref page_use_prot_interface_handle
/// section above described using @b nil::marshalling::option::handler option, which
/// adds polymorphic @b dispatch() member function to the common interface class
/// (@b MyMessage). The provided handling class (@b MyHandler) is expected
/// to define @b handle() member function for every message class it is expected to
/// handle.
/// @code
/// class MyHandler
/// {
/// public:
///     void handle(my_protocol::Message1<MyMessage>& msg) {...}
///     void handle(my_protocol::Message5<MyMessage>& msg) {...}
///     ...
/// }
/// @endcode
/// and a single @b handle() member function that receives common message
/// interface class for all the messages that need to be ignored or handled
/// in some other common way. If this function is not added, the compilation
/// may fail.
/// @code
/// class MyHandler
/// {
/// public:
///     ...
///     void handle(MyMessage& msg) {} // do nothing for all other messages
/// }
/// @endcode
/// For example, let's assume that @b MyHandler defines message to properly
/// handle @b Message1, but doesn't care about @b Message2. In this case
/// @code
/// std::unique_ptr<MyMessage> msg1(new my_protocol::Message1<MyMessage>);
/// std::unique_ptr<MyMessage> msg2(new my_protocol::Message2<MyMessage>);
/// MyHandler handler;
///
/// msg1->dispatch(handler); // invokes handle(my_protocol::Message1<MyMessage>&)
/// msg2->dispatch(handler); // invokes handle(MyMessage&)
/// @endcode
///
/// @b NOTE, that @b MyMessage class is only forward declared when 
/// @ref page_use_prot_interface (@b MyMessage), but needs to be properly
/// defined (included if in separate file) when defining @ref page_use_prot_transport.
///
/// @subsection page_use_prot_handling_multi Having Multiple Handlers
/// There may be a need for being able to dispatch message for multiple independent handlers. 
/// Good example would be having a state-machine, where every state processes
/// the same message in different way. It is simple to implement by just
/// defining the handling functions as @b virtual.
/// @code
/// class MyHandler
/// {
/// public:
///     virtual void handle(my_protocol::Message1<MyMessage>& msg) = 0;
///     virtual void handle(my_protocol::Message2<MyMessage>& msg) = 0;
///     virtual void handle(my_protocol::Message3<MyMessage>& msg) = 0;
///     ...
/// };
/// @endcode
/// Defining the concrete handlers:
/// @code
/// class Handler1 : public MyHandler
/// {
/// public:
///     virtual void handle(my_protocol::Message1<MyMessage>& msg) override {...};
///     virtual void handle(my_protocol::Message2<MyMessage>& msg) override {...};
///     virtual void handle(my_protocol::Message3<MyMessage>& msg) override {...};
///     ...
/// };
///
/// class Handler2 : public MyHandler
/// {
/// public:
///     virtual void handle(my_protocol::Message1<MyMessage>& msg) override {...};
///     virtual void handle(my_protocol::Message2<MyMessage>& msg) override {...};
///     virtual void handle(my_protocol::Message3<MyMessage>& msg) override {...};
///     ...
/// };
/// @endcode
/// Now, any of the handlers may be used to handle the message:
/// @code
/// std::unique_ptr<MyMessage> msg(.../* some message object */);
/// Handler1 handler1;
/// Handler2 handler2;
///
/// msg->dispatch(handler1); // Handle with handler1
/// msg->dispatch(handler2); // Handle with handler2
/// @endcode
///
/// @subsection page_use_prot_handling_generic Generic handler
/// The Marshalling library provides some help in defining custom message handlers.
/// There is @ref nil::marshalling::generic_handler class that receives at least two template
/// parameters. The first one is a common interface class for all the handled messages
/// (@b MyMessage). The second template parameter is
/// all the types of all the custom messages the handler is supposed to handle,
/// bundled into std::tuple. Remember defining a bundle of messages (@b MyInputMessages) that need
/// to be recognised during @ref page_use_prot_transport_read? It's probably
/// a good place to reuse it or define a new tuple if there is a mismatch.
/// @code
/// using MyMessagesToHandle = MyInputMessages;
/// @endcode
/// As the result the nil::marshalling::generic_handler implements @b virtual @b handle()
/// function for all the provided messages including the provided interface one.
/// The code that automatically generated by @b nil::marshalling::generic_message is equivalent
/// to the one below.
/// @code
/// template<>
/// class generic_handler<MyMessage, MyMessagesToHandle>
/// {
/// public:
///     virtual void handle(MyMessage& msg) {} // Do nothing
///
///     virtual void handle(my_protocol::Message1<MyMessage>& msg)
///     {
///         this->handle(static_cast<MyMessage&>(msg)); // invoke default handling
///     }
///
///     virtual void handle(my_protocol::Message2<MyMessage>& msg)
///     {
///         this->handle(static_cast<MyMessage&>(msg)); // invoke default handling
///     }
///
///     ...
/// };
/// @endcode
/// Now, what remains is to inherit from nil::marshalling::generic_handler and override
/// the functions that need to be overridden:
/// @code
/// class MyHandler : public nil::marshalling::generic_handler<MyMessage, all_messages_type>
/// {
/// public:
///     // Enable polymorphic delete
///     virtual ~MyHandler() {}
///
///     // Overriding the default handling function
///     virtual handle(MyMessage& msg) override
///     {
///         std::cout << "Ignoring message with ID: " << msg.get_id() << std::endl;
///     }
///
///     // Overriding handling of Message1
///     virtual handle(my_protocol::Message1<MyMessage>& msg) override
///     {
///         ...; // Handle Message1
///     }
/// };
/// @endcode
/// Pay attention that @ref nil::marshalling::generic_handler doesn't declare its destructor as virtual.
/// If the handler object requires support for polymorphic delete (destruction),
/// make sure to declare its destructor as virtual.
///
/// @subsection page_use_prot_handling_result Returning Handling Result
/// All the examples above used @b void as a return type from handling functions. It
/// is possible, however, to return value of handling result. In order to achieve
/// this the handler class needs to define inner @b RetType type and all the
/// @b handle() functions must return it. For example:
/// @code
/// class MyHandler
/// {
/// public:
///     // Return type of all the handle() functions
///     typedef bool RetType;
///
///     bool handle(my_protocol::Message1<MyMessage>& msg) {...}
///     bool handle(my_protocol::Message2<MyMessage>& msg) {...}
///     bool handle(my_protocol::Message3<MyMessage>& msg) {...}
///     ...
/// };
/// @endcode
/// If inner @b RetType type is defined, it is propagated to be also the return type of
/// the @ref nil::marshalling::Message::dispatch() member function as well. As the result the developer may
/// use constructs like this:
/// @code
/// bool result = msg->dispatch(handler);
/// @endcode
///
/// If @ref nil::marshalling::generic_handler class is used to define the handler class, its
/// third template parameter (which defaults to @b void), can be used to
/// specify the return type of handling functions.
///
/// @section page_use_prot_extra_transport Extra Transport Values
/// Some protocols may use extra values in their transport information, which 
/// may influence the way how message payload is being read and/or message 
/// object being handled. Good example would be having a protocol version, 
/// which defines what message payload fields were serialized and which were
/// not (because they were introduced in later version of the protocol). 
/// Such extra information is stored in the message object itself. If this is
/// the case, the protocol definition is expected to use 
/// @ref nil::marshalling::option::extra_transport_fields option in addition to specifying
/// serialization endian and message ID type (described in @ref
/// page_use_prot_interface).
/// (see @ref page_field_tutorial) and bundled in @b std::tuple:
/// @code
/// namespace my_protocol
/// {
/// 
/// // field_type describing protocol version.
/// using MyVersionField = 
///     nil::marshalling::types::IntValue<
///         MyFieldBase, 
///         std::uint16_t,
///         nil::marshalling::option::default_num_value<5> // Implementing v5 of the protocol by default
///     >;
///
/// // Relevant extra transport fields, bundled in std::tuple
/// using MyExtraTransportFields =
///     std::tuple<
///         MyVersionField
///     >;
///
/// template <typename... TOptions>
/// class Message : public
///     nil::marshalling::Message<
///         nil::marshalling::option::big_endian,
///         nil::marshalling::option::msg_id_type<msg_id>,
///         nil::marshalling::option::extra_transport_fields<MyExtraTransportFields>,
///         TOptions...
///     >
/// {
/// public:
///     MARSHALLING_MSG_TRANSPORT_FIELDS_ACCESS(version)
/// };
///
/// } // namespace my_protocol
/// @endcode
/// Usage of @ref nil::marshalling::option::extra_transport_fields option as well as
/// @ref MARSHALLING_MSG_TRANSPORT_FIELDS_ACCESS() macro in the message class definition
/// is equivalent to having the following types and member functions defined
/// @code
/// namespace my_protocol
/// {
/// 
/// template <typename... TOptions>
/// class Message : public
///     nil::marshalling::Message<
///         nil::marshalling::option::big_endian,
///         nil::marshalling::option::msg_id_type<msg_id>,
///         TOptions...
///     >
/// {
/// public:
///     // type of extra fields
///     using transport_fields_type = MyExtraTransportFields;
///
///     // Accessors for defined transport fields
///     transport_fields_type& transport_fields() { return m_transportFields; }
///     const transport_fields_type& transport_fields() const { return m_transportFields; }
///
///     // Indices to access extra transport fields
///     enum TransportFieldIdx
///     {
///         TransportFieldIdx_version,
///         TransportFieldIdx_numOfValues
///     };
///
///     // Access the "version" extra transport field
///     auto transportField_version() -> decltype(std::get<TransportFieldIdx_version>(transport_fields()))
///     {
///         return std::get<TransportFieldIdx_version>(transport_fields());
///     }
///
///     // Access the "version" extra transport field (const version)
///     auto transportField_version() const -> decltype(std::get<TransportFieldIdx_version>(transport_fields()))
///     {
///         return std::get<TransportFieldIdx_version>(transport_fields());
///     }
/// };
///
/// } // namespace my_protocol
/// @endcode
/// For reference see also description of @ref nil::marshalling::Message::transport_fields()
/// member function.
///
/// Access to the version information given a reference to message object may
/// now be implemented as:
/// @code
/// void handle(my_protocol::Message<>& msg)
/// {
///     // Retrieve the version numeric value
///     auto versionValue = msg.transportField_version().value();
///
///     ... // do something with version information
/// }
/// @endcode
/// @b NOTE, that the defined "extra transport fields" are there to attach 
/// some extra information, delivered as part of transport framing, to message 
/// object itself. These fields are @b NOT getting serialized / deserialized when message
/// object (payload) being read / written.
///
/// The @ref nil::marshalling::Message interface class defines @ref nil::marshalling::Message::has_transport_fields()
/// static constexpr member function, which may be used at compile time to 
/// determine whether the @ref nil::marshalling::option::extra_transport_fields option has been used, i.e.
/// the message interface class defines mentioned earlier
/// types and functions.
///
/// @subsection page_use_prot_extra_transport_version Built-in Version Support
/// The @b Marshalling library contain a built-in protocol version support when
/// version info is provided within @ref page_use_prot_extra_transport. To support
/// this feature, the
/// message interface definition class needs to use @ref nil::marshalling::option::version_in_extra_transport_fields
/// option, in addition to @ref nil::marshalling::option::extra_transport_fields option itself, to
/// specify which field is @b version.
/// @code
/// namespace my_protocol
/// {
/// 
/// // field_type describing protocol version.
/// using MyVersionField = nil::marshalling::types::IntValue<...>;
///
/// // Relevant extra transport fields, bundled in std::tuple
/// using MyExtraTransportFields =
///     std::tuple<
///         MyVersionField
///     >;
///
/// template <typename... TOptions>
/// class Message : public
///     nil::marshalling::Message<
///         nil::marshalling::option::big_endian,
///         nil::marshalling::option::msg_id_type<msg_id>,
///         nil::marshalling::option::extra_transport_fields<MyExtraTransportFields>,
///         nil::marshalling::option::version_in_extra_transport_fields<0>
///         TOptions...
///     >
/// {
///     ...
/// };
///
/// } // namespace my_protocol
/// @endcode
/// Usage of @ref nil::marshalling::option::version_in_extra_transport_fields option generates
/// inner @b version_type type (see @ref nil::marshalling::Message::version_type) as well
/// as @b version() access functions (see @ref nil::marshalling::Message::version()) for direct
/// access to it. It is equivalent to having the following functions defined:
/// @code
/// namespace my_protocol
/// {
/// 
/// template <typename... TOptions>
/// class Message : public
///     nil::marshalling::Message<...>
/// {
/// public:
///     ...
///     // type of extra fields
///     using version_type = ...; // Equals to value_type of the relevant field.
///
///     // Accessors for the version info
///     version_type version();
///     const version_type& version();
/// };
///
/// } // namespace my_protocol
/// @endcode
/// @b NOTE, that updating the version information only modifies the value
/// of the relevant transport fields itself. The message contents are not
/// being updated. There is a need to invoke @b do_fields_version_update() member
/// function (see @ref nil::marshalling::MessageBase::do_fields_version_update()),
/// which will do the job of updating message 
/// contents accordingly.
/// @code
/// using MyMessage1 = my_protocol::MyMessage<...>;
/// MyMessage1 msg;
/// msg.version() = 5U; // Update the version
/// msg.do_fields_version_update(); // Update the message contents that depend on version
/// @endcode 
/// The @b refresh functionality (direct or polymorphic) also contains update
/// of the fields' version, which can be used instead.
/// @code
/// void updateVersion(MyMessage& msg)
/// {
///     msg.version() = 5U;
///     msg.refresh(); // Polymorphically update the message contents accordingly
/// }
/// @endcode
///
/// @section page_use_prot_pseudo_transport Pseudo Transport Values
/// Some communication protocols have values (such as protocol version information),
/// which are reported in the payload of one of the messages and may influence
/// the way how other messages being deserialized and/or handled. Usually it is
/// some kind of @b CONNECT message. Such scenario is implemented in the
/// very similar way to @ref page_use_prot_extra_transport. The protocol stack
/// is still defined using @ref nil::marshalling::protocol::TransportValueLayer but with @ref
/// nil::marshalling::option::pseudo_value option. Such layer contains the "pseudo" field in
/// its internal data members and pretends to read it during @b read operation.
///
/// Let's assume the protocol framing is defined to be
/// @code
/// SIZE | ID | PAYLOAD
/// @endcode
/// but there is some kind of @b CONNECT message that reports client protocol version.
/// The transport framing will probably be defined as if it handles the following
/// stack.
/// @code
/// SIZE | ID | VERSION (pseudo) | PAYLOAD
/// @endcode
/// The transport framing is expected to be defined as below providing an access
/// to the VERSION handling layer:
/// @code
/// namespace my_protocol
/// {
///
/// template <
///     typename TMessage, // common interface class defined by the application
///     typename TInputMessages = all_messages_type<TMessage>, // Input messages that need to be recognised
///     typename TAllocationOptions = nil::marshalling::option::empty_option, // Extra options for MsgIdLayer
///     typename TPayloadOptions = nil::marshalling::option::empty_option // Extra options for payload storage
/// >
/// struct ProtocolStack : public 
///     MySizePrefix<TMessage, TInputMessages, TAllocationOptions, TPayloadOptions> 
/// {
///     MARSHALLING_PROTOCOL_LAYERS_ACCESS(payload, version, id, size);
/// };
///
/// } // namespace my_protocol
/// @endcode
/// Then after reception and handling of the mentioned @b CONNECT message, the
/// stored pseudo version field may be accessed using @b pseudo_field() member
/// function of @ref nil::marshalling::protocol::TransportValueLayer layer (see @ref
/// nil::marshalling::protocol::TransportValueLayer::pseudo_field()) and updated with
/// reported value.
/// @code
/// ProtStack protStack; // Protocol stack object
/// protStack.layer_version().pseudo_field().value() = connectMsg.field_version().value();
/// @endcode
/// From now on every received message will have appropriate extra transport field
/// updated accordingly right after receiving of the message and before its @b
/// read operation being performed.
///
/// @section page_use_prot_msg_customisation Application Specific Customisation of Messages
/// When most of the messages are uni-directional, i.e. are either only sent or
/// only received, then it may make sense to split the common message interface
/// class @b MyMessage (see @ref page_use_prot_interface) into two 
/// interface classes: for @b input and for @b output. It will save the generation
/// of unnecessary virtual functions which are not used, but occupy space.
/// @code
/// using MyInputMessage = 
///     my_protocol::Message<
///         nil::marshalling::option::read_iterator<const std::uint8_t*>, // polymorphic read
///         nil::marshalling::option::handler<MyHandler> // polymorphic dispatch
///     >;
///
///  using MyOutputMessage = 
///     my_protocol::Message<
///         nil::marshalling::option::write_iterator<std::uint8_t*>, // polymorphic write
///         nil::marshalling::option::id_info_interface, // polymorphic ID retrieve
///         nil::marshalling::option::length_info_interface // polymorphic serialization length retrieve
///     >;
///
/// using MyInputMessage1 = my_protocol::Message1<MyInputMessage>;
/// using MyInputMessage2 = my_protocol::Message2<MyInputMessage>;
/// using MyInputMessage3 = my_protocol::Message3<MyInputMessage>;
/// ...
///
/// using MyOutputMessage7 = my_protocol::Message7<MyOutputMessage>;
/// using MyOutputMessage8 = my_protocol::Message8<MyOutputMessage>;
/// using MyOutputMessage9 = my_protocol::Message9<MyOutputMessage>;
/// ...
///
/// @endcode
/// There may be also an opposite case, when most of the messages are bi-directional,
/// while only few go one way. For most applications the single common
/// message interface will do the job. However generating unnecessary virtual
/// functions for bare-metal application may be a heavy price to pay, especially
/// when ROM size is small. The @b Marshalling library provides several
/// options that inhibit generation of virtual functions. These extra options 
/// need to be passed to @ref nil::marshalling::MessageBase class when defining a message
/// class. Available options are:
/// @li @ref nil::marshalling::option::no_read_impl
/// @li @ref nil::marshalling::option::no_write_impl
/// @li @ref nil::marshalling::option::no_valid_impl
/// @li @ref nil::marshalling::option::no_length_impl
///
/// In order to be able to pass these extra options to message definition classes,
/// the support from the latter is required. If the protocol definition
/// follows a recommended approach the message definition is expected to
/// reuse extra protocol options structure (@b DefaultOptions) described earlier.
/// @code
/// namespace my_protocol
/// {
///
/// // Allow passing extra options to messages as well
/// struct DefaultOptions
/// {
///     struct message
///     {
///         using Message1 = nil::marshalling::option::empty_option;
///         using Message2 = nil::marshalling::option::empty_option;
///         ...
///     };
/// };
/// 
/// namespace message
/// {
///
/// template <typename TBase, typename TOpt = DefaultOptions>
/// class Message1 : public 
///     nil::marshalling::MessageBase<
///         TBase, 
///         nil::marshalling::option::static_num_id_impl<MsgId_Message1>,
///         nil::marshalling::option::fields_impl<Message1Fields<TOpt>::All>,
///         nil::marshalling::option::msg_type<Message1<TBase, TOpt> >,
///         typename TOpt::message::Message1 // Extra options 
///     >
/// {
///     ...
/// };
///
/// } // namespace message
///
/// } // namespace my_protocol
/// @endcode
/// As an example let's assume, that @b Message1 is only sent by the
/// application, but never received, and @b Message 2 is the opposite, only
/// received by never sent. In this case defining the following options
/// structure and passing them in to message definition classes will work
/// @code
/// struct MyOptions : public my_protocol::DefaultOptions
/// {
///     struct message : public my_protocol::DefaultOptions::message
///     {
///         using Message1 = nil::marshalling::option::no_read_impl;
///         using Message2 = nil::marshalling::option::no_write_impl;
///     };
/// };
///
/// using MyMessage1 = my_protocol::Message1<MyMessage, MyOptions>;
/// using MyMessage2 = my_protocol::Message2<MyMessage, MyOptions>;
/// @endcode
///
/// @section page_use_prot_msg_extension Message Interface Extension
/// Sometimes the public interface of the messages, generated by the
/// @b Marshalling library out of available options passed to @ref nil::marshalling::Message,
/// may be insufficient for some applications and its interface needs to be extended
/// with custom member functions. It is easy to achieve by
/// just implementing required function in common message interface class
/// @code
/// class MyMessage : public my_protocol::Message<...>
/// {
/// public:
///     void someFunc()
///     {
///         someFuncImpl();
///     }
///
/// protected:
///     virtual void someFuncImpl() = 0;
/// };
/// @endcode
/// All the protocol messages must also be extended in order to implement
/// missing virtual function
/// @code
/// class MyMessage1 : public my_protocol::Message1<MyMessage>
/// {
/// protected:
///     virtual void someFuncImpl() override
///     {
///         ...
///     }
/// };
/// @endcode
/// Don't forget to bundle newly defined messages in @b std::tuple and pass 
/// them to @ref page_use_prot_transport definition or @ref page_use_prot_handling_generic
/// when needed.
/// @code
/// using MyInputMessages = 
///     std::tuple<
///         MyMessage1, 
///         MyMessage2,
///         ...
///     >;
///
/// using MyProtocolStack = my_protocol::ProtocolStack<MyMessage, MyInputMessages>;
/// using MyHandler = nil::marshalling::generic_handler<MyMessage, MyInputMessages>;
/// ...
/// @endcode
///
